• 贪心 BZOJ 3671:[Noi2014]随机数生成器


    Description

     

    Input

    第 1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子。第2行包含三个整数 N,M,Q ,表示小H希望生成一个1到 N×M 的排列来填入她 N 行 M 列的棋盘,并且小H在初始的 N×M 次交换操作后,又进行了 Q 次额外的交换操作。接下来 Q 行,第 i 行包含两个整数 u_i,v_i,表示第 i 次额外交换操作将交换 T_(u_i )和 T_(v_i ) 的值。

    Output

    输出一行,包含 N+M-1 个由空格隔开的正整数,表示可以得到的字典序最小的路径序列。

    Sample Input

    1 3 5 1 71
    3 4 3
    1 7
    9 9
    4 9

    Sample Output

    1 2 6 8 9 12

    HINT

    本题的空间限制是 256 MB,请务必保证提交的代码运行时所使用的总内存空间不超过此限制。

    一个32位整数(例如C/C++中的int和Pascal中的Longint)为4字节,因而如果在程序中声明一个长度为 1024×1024 的32位整型变量的数组,将会占用 4 MB 的内存空间。



    2≤N,M≤5000

    0≤Q≤50000

    0≤a≤300

    0≤b,c≤108

    0≤x0<d≤1081≤ui,vi≤N×M




       这题先生成数据,应用贪心的思想,优先取字典序最小的,然后删除排除的情况,总之换个角度看就水过了。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 int n,m,Q;
     6 long long x,a,b,c,d;
     7 long long Getnxt(){
     8     return (1ll*a*x*x+1ll*b*x+1ll*c)%d;
     9 }
    10 const int maxn=5010;
    11 
    12 int map[maxn][maxn];
    13 int pos[maxn*maxn];
    14 int U[maxn],D[maxn],L[maxn],R[maxn];
    15 
    16 int main(){
    17     scanf("%lld%lld%lld%lld%lld",&x,&a,&b,&c,&d);
    18     scanf("%d%d%d",&n,&m,&Q);
    19     for(int i=1;i<=n;i++)
    20         for(int j=1,p;j<=m;j++){
    21             x=Getnxt();
    22             p=x%(1ll*(i-1)*m+j)+1;
    23             map[i][j]=(i-1)*m+j;
    24             swap(map[i][j],map[(p-1)/m+1][(p-1)%m+1]);    
    25         }
    26     for(;Q--;){
    27         int u,v;
    28         scanf("%d%d",&u,&v);
    29         swap(map[(u-1)/m+1][(u-1)%m+1],map[(v-1)/m+1][(v-1)%m+1]);
    30     }    
    31     for(int i=1;i<=n;i++)
    32         for(int j=1;j<=m;j++)    
    33             pos[map[i][j]]=(i-1)*m+j;
    34     
    35     int cnt=0,x,y;
    36     
    37     for(int i=1;i<=n;i++)
    38         R[i]=m+1;
    39     for(int i=1;i<=m;i++)
    40         D[i]=n+1;    
    41     for(int i=1;i<=n*m;i++){
    42         x=(pos[i]-1)/m+1;y=(pos[i]-1)%m+1;
    43         if(y>L[x]&&y<R[x]&&x>U[y]&&x<D[y]){
    44             ++cnt;
    45             for(int j=x+1;j<=n;j++)
    46                 L[j]=max(L[j],y-1);
    47             for(int j=x-1;j>=1;j--)    
    48                 R[j]=min(R[j],y+1);
    49             for(int j=y+1;j<=m;j++)    
    50                 U[j]=max(U[j],x-1);
    51             for(int j=y-1;j>=1;j--)
    52                 D[j]=min(D[j],x+1);
    53             
    54             if(cnt!=n+m-1)
    55                 printf("%d ",i);
    56             else
    57                 printf("%d",i);
    58         }
    59         if(cnt==n+m-1)
    60             break;
    61     }
    62     return 0;
    63 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    Python 从入门到实践
    Python 斐波那契数列
    Python 纸牌游戏
    Python hangman小游戏
    BC #49 1001 Untitled
    BC#50 1003 The mook jong
    BC #50 1001 Distribution money
    vector
    stack
    queue
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5302393.html
Copyright © 2020-2023  润新知