UOJ #6. 【NOI2014】随机数生成器 贪心

这道题太 tm 卡内存了.   

不知道这样做意义何在,是在考察选手卡常能力吗 ? 

思路没啥说的,整个棋盘的形态我们是知道的. 

那么显然从小到大把数往棋盘里填,然后我们每次不可以选的是一个左下角和右上角区域,暴力覆盖就行.  

覆盖的时候要判一下什么时候 break,来保证每个地方只被覆盖依次.   

code: 

#include <bits/stdc++.h>  
#define N 5005 
#define M 50007       
#define ll long long 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;  
int mod,n,m,Q;          
int val[N*N],pos[N*N];   
bool mark[N][N];               
int main() 
{ 
    // setIO("input");                  
    int A,B,C,t=0; 
    scanf("%d%d%d%d%d%d%d%d",&pos[0],&A,&B,&C,&mod,&n,&m,&Q);    
    for(int i=1;i<=n*m;++i)  
        pos[i]=(ll)(1ll*A*pos[i-1]%mod*pos[i-1]%mod+1ll*B*pos[i-1]%mod+C)%mod;
    for(int i=1;i<=n*m;++i) val[i]=i;   
    for(int i=1;i<=n*m;++i) swap(val[i],val[(pos[i]%i)+1]);   
    for(int i=1;i<=Q;++i) 
    {
        int u,v; 
        scanf("%d%d",&u,&v),swap(val[u],val[v]);   
    }                       
    for(int i=1;i<=n*m;++i)  pos[val[i]]=i;    
    for(int i=1;i<=n*m;++i) 
    {   
        int x=(pos[i]-1)/m+1,y=(pos[i]-1)%m+1;   
        if(mark[x][y])  continue;   
        printf("%d ",i);         
        for(int a=x+1;a<=n;++a) 
        {   
            if(a>n||y-1<1)  break; 
            if(mark[a][y-1])  
                break;    
            for(int b=y-1;b>=1;--b) 
            {         
                if(mark[a][b]) break;   
                mark[a][b]=1; 
                // vis[aa[a][b]]=1;       
            }     
        }        
        for(int a=x-1;a>=1;--a) 
        { 
            if(a<1||y+1>m)  break;      
            if(mark[a][y+1]) break; 
            for(int b=y+1;b<=m;++b) 
            {      
                if(mark[a][b]) break;   
                mark[a][b]=1; 
                // vis[aa[a][b]]=1;   
            }
        }
    }
    // for(int i=1;i<=n*m;++i) if(an[i]) printf("%d ",i);   
    return 0;  
}

  

原文地址:https://www.cnblogs.com/guangheli/p/12569290.html