随机化80分做法求优化
查看原帖
随机化80分做法求优化
1381233
Torrentolf楼主2024/11/13 19:53
#include<iostream>
#include<cstring>
#include<ctime>
#include<bitset>
#include<random>
#include<algorithm>
#include<vector>
using namespace std ;
namespace IO
{
	namespace Read
	{
		#define isdigit(ch) (ch >= '0' && ch <= '9')
		#define SIZE (1 << 16)
		char buf[SIZE] , *_now = buf , *_end = buf ;
		char getchar()
		{
			if(_now == _end)
			{
				_now = _end = buf ;
				_end += fread(buf , 1 , SIZE , stdin) ;
				if(_now == _end)
					return EOF ;
			}
			return *(_now++) ;
		}
		template<typename T>
		void read(T& w)
		{
			w = 0 ;
			short f = 1 ;
			char ch = getchar() ;
			while(!isdigit(ch))
			{
				if(ch == '-')
					f = -1 ;
				ch = getchar() ;
			}
			while(isdigit(ch))
				w = (w << 1) + (w << 3) + (ch ^ 48) , ch = getchar() ;
			w *= f ;
		}
		#define sb(ch) (ch == ' ' || ch == '\n')
		void read(char* s)
		{
			char ch = getchar() ;
			while(sb(ch))
				ch = getchar() ;
			int len = 0 ;
			while(!sb(ch))
				s[len++] = ch , ch = getchar() ;
		}
		void read(string& s)
		{
			char ch = getchar() ;
			while(sb(ch))
				ch = getchar() ;
			while(!sb(ch))
				s.push_back(ch) , ch = getchar() ;
		}
		#undef sb
		template<typename a , typename...T>
		void read(a& s , T&...ss)
		{
			read(s) , read(ss...) ;
		}
		void read(double& w)
		{
			w = 0 ;
			short f = 1 ;
			char ch = getchar() ;
			while(!isdigit(ch))
			{
				if(ch == '-')
					f = -1 ;
				ch = getchar() ;
			}
			while(isdigit(ch))
				w = w * 10 + (ch ^ 48) , ch = getchar() ;
			if(ch == '.')
			{
				ch = getchar() ;
				int len = 0 ;
				while(isdigit(ch))
					w = w * 10 + (ch ^ 48) , ch = getchar() , ++len ;
				while(len)
					w /= 10 , --len ;
			}
			w *= f ;
		}
		void read(float& w)
		{
			w = 0 ;
			short f = 1 ;
			char ch = getchar() ;
			while(!isdigit(ch))
			{
				if(ch == '-')
					f = -1 ;
				ch = getchar() ;
			}
			while(isdigit(ch))
				w = w * 10 + (ch ^ 48) , ch = getchar() ;
			if(ch == '.')
			{
				ch = getchar() ;
				int len = 0 ;
				while(isdigit(ch))
					w = w * 10 + (ch ^ 48) , ch = getchar() , ++len ;
				while(len)
					w /= 10 , --len ;
			}
			w *= f ;
		}
		void read(long double& w)
		{
			w = 0 ;
			short f = 1 ;
			char ch = getchar() ;
			while(!isdigit(ch))
			{
				if(ch == '-')
					f = -1 ;
				ch = getchar() ;
			}
			while(isdigit(ch))
				w = w * 10 + (ch ^ 48) , ch = getchar() ;
			if(ch == '.')
			{
				ch = getchar() ;
				int len = 0 ;
				while(isdigit(ch))
					w = w * 10 + (ch ^ 48) , ch = getchar() , ++len ;
				while(len)
					w /= 10 , --len ;
			}
			w *= f ;
		}
		template<typename T>
		void read(T* s , int sta , int len)
		{
			for(int i = 0 ; i < len ; ++i)
				read(s[i + sta]) ;
		}
		class qistream
		{
			public:
			template<typename T>
			qistream& operator>>(T& a)
			{
				read(a) ;
				return *this ;
			}
		} qcin ;
	}
	namespace Write
	{
		#define SIZE (1 << 16)
		char buf[SIZE] , *p = buf ;
		void flush()
		{
			fwrite(buf , 1 , p - buf , stdout) ;
			p = buf ;
		}
		void putchar(char ch)
		{
			if(p == buf + SIZE)
				flush() ;
			*p = ch ;
			++p ;
		}
		class Flush{public:~Flush(){flush() ;};}_;
		template<typename T>
		void write(T x)
		{
			char st[50] ;
			int len = 0 ;
			if(x < 0)
				putchar('-') , x = -x ;
			do
			{
				st[++len] = x % 10 + '0' ;
				x /= 10 ;
			} while(x) ;
			while(len)
				putchar(st[len--]) ;
		}
		void write(char c)
		{
			putchar(c) ;
		}
		void write(const char* s)
		{
			int siz = strlen(s) ;
			for(int i = 0 ; i < siz ; ++i)
				putchar(s[i]) ;
		}
		void write(string& s)
		{
			int siz = s.size() ;
			for(int i = 0 ; i < siz ; ++i)
				putchar(s[i]) ;
		}
		template<typename a , typename...T>
		void write(a& s , T&...ss)
		{
			write(s) , write(ss...) ;
		}
		void write(double x , int len = 6)
		{
			if(x < 0)
				write('-') , x = -x ;
			__int128 sb = __int128(x) ;
			x -= sb ;
			int spar = 0 ;
			for(int i = 0 ; i <= len ; ++i)
			{
				x *= 10 ;
				if(int(x) == 0)
					++spar ;
			}
			__int128 ssb = __int128(x) ;
			if(ssb % 10 >= 5)
				ssb += 10 ;
			ssb /= 10 ;
			write(sb) , write('.') ;
			for(int i = 1 ; i <= spar ; ++i)
				write('0') ;
			write(ssb) ;
		}
		void write(float x , int len = 6)
		{
			if(x < 0)
				write('-') , x = -x ;
			__int128 sb = __int128(x) ;
			x -= sb ;
			int spar = 0 ;
			for(int i = 0 ; i <= len ; ++i)
			{
				x *= 10 ;
				if(int(x) == 0)
					++spar ;
			}
			__int128 ssb = __int128(x) ;
			if(ssb % 10 >= 5)
				ssb += 10 ;
			ssb /= 10 ;
			write(sb) , write('.') ;
			for(int i = 1 ; i <= spar ; ++i)
				write('0') ;
			write(ssb) ;
		}
		void write(long double x , int len = 6)
		{
			if(x < 0)
				write('-') , x = -x ;
			__int128 sb = __int128(x) ;
			x -= sb ;
			int spar = 0 ;
			for(int i = 0 ; i <= len ; ++i)
			{
				x *= 10 ;
				if(int(x) == 0)
					++spar ;
			}
			__int128 ssb = __int128(x) ;
			if(ssb % 10 >= 5)
				ssb += 10 ;
			ssb /= 10 ;
			write(sb) , write('.') ;
			for(int i = 1 ; i <= spar ; ++i)
				write('0') ;
			write(ssb) ;
		}
		template<typename T>
		void write(T* s , int sta , int len , char c)
		{
			int en = sta + len - 1 ;
			for(int i = sta ; i <= en ; ++i)
				write(s[i]) , write(c) ;
		}
		template<typename T>
		void write(T* s , int sta , int len , char* ss)
		{
			int en = sta + len - 1 ;
			for(int i = sta ; i <= en ; ++i)
				write(s[i]) , write(ss) ;
		}
		class qostream
		{
			public:
			template<typename T>
			qostream& operator<<(T x)
			{
				write(x) ;
				return *this ;
			}
		} qcout ;
	}
	using namespace Read ;
	using namespace Write ;
}
using namespace IO ;
vector<int> st[60] ;
vector<int> tmp[60] ;
int n = 0 , m = 0 ;
int op[405] = {} , len = 0 ;
bitset<60> use ;
int sp = 0 ;
struct opr
{
    int fro , to ;
} ;
vector<opr> ope ;
int cou[60] = {} ;
inline void move(int x , int y)
{
    st[y].push_back(st[x].back()) ;
    st[x].pop_back() ;
    ope.push_back((opr){x , y}) ;
}
inline void ti(int x , int color , int fu)
{
    int cnt = 0 ;
    for(unsigned i = 0 ; i < st[x].size() ; ++i)
        if(st[x][i] == color)
            ++cnt ;
    cou[x] = cnt ;
    if(cnt == 0)
        return ;
    if(m - cnt >= cnt)
    {
        for(int i = 1 ; i <= cnt ; ++i)
            move(fu , sp) ;
        while(cnt)
        {
            int now = st[x].back() ;
            if(now == color)
                move(x , fu) , --cnt ;
            else
                move(x , sp) ;
        }
        int siz = st[x].size() ;
        for(int i = 1 ; i <= m - cou[x] - siz ; ++i)
            move(sp , x) ;
        for(int i = 1 ; i <= cou[x] ; ++i)
            move(fu , x) ;
        while(!st[sp].empty())
            move(sp , fu) ;
    }
    else
    {
        for(int i = 1 ; i <= m - cnt ; ++i)
            move(fu , sp) ;
        while(cnt)
        {
            int now = st[x].back() ;
            if(now == color)
                move(x , sp) , --cnt ;
            else
                move(x , fu) ;
        }
        int siz = st[x].size() ;
        for(int i = 1 ; i <= m - cou[x] - siz ; ++i)
            move(fu , x) ;
        for(int i = 1 ; i <= cou[x] ; ++i)
            move(sp , x) ;
        while(!st[sp].empty())
            move(sp , fu) ;
    }
}
inline void clear(int x)
{
    while(!st[x].empty())
    {
        int pu = 0 ;
        for(int i = 1 ; i <= n + 1 ; ++i)
            if(!use[i] && i != x && st[i].size() < m)
            {
                pu = i ;
                break ;
            }
        while(st[pu].size() < m)
            move(x , pu) ;
    }
    sp = x ;
}
int main()
{
    srand(time(0)) ;
    mt19937 myrand(rand()) ;
    qcin>>n>>m ;
    for(int i = 1 ; i <= n ; ++i)
    {
        for(int j = 1 ; j <= m ; ++j)
        {
            int a = 0 ;
            qcin>>a ;
            st[i].push_back(a) ;
            tmp[i].push_back(a) ;
        }
    }
    for(int i = 1 ; i <= n ; ++i)
        op[++len] = i ;
    while(1)
    {
    	sp = n + 1 ;
        for(int i = 1 ; i < n ; ++i)
        {
            memset(cou , 0 , sizeof cou) ;
            int col = op[i] ;
            for(int j = 1 ; j <= n + 1 ; ++j)
            {
                if(j == sp || use[j])
                    continue ;
                for(int k = 1 ; k <= n + 1 ; ++k)
                    if(k != sp && k != j)
                    {
                        ti(j , col , k) ;
                        break ;
                    }
            }
            for(int j = 1 ; j <= n + 1 ; ++j)
            {
                if(j == sp || use[j] || cou[j] == 0)
                    continue ;
                for(int k = 1 ; k <= cou[j] ; ++k)
                    move(j , sp) ;
            }
            use[sp] = true ;
            clear(sp - 1) ;
        }
        if(ope.size() <= 820000)
            break ;
        shuffle(op + 1 , op + n + 1 , myrand) ;
        ope.clear() ;
        use.reset() ;
        for(int i = 1 ; i <= n ; ++i)
        {
            st[i].clear() ;
            for(unsigned j = 0 ; j < tmp[i].size() ; ++j)
                st[i].push_back(tmp[i][j]) ;
        }
        st[n + 1].clear() ;
    }
    qcout<<ope.size()<<'\n' ;
    for(unsigned i = 0 ; i < ope.size() ; ++i)
        qcout<<ope[i].fro<<' '<<ope[i].to<<'\n' ;
    return 0 ;
}
2024/11/13 19:53
加载中...