bzoj3671[Noi2014]随机数生成器(贪心)

题面太长就不粘了
贪心思路就是先按值从小到大排序,然后从小往大选可选的数就好
每选一个数,就将这个数的左下方和右下方标记为不可选即可(注意break来保证时间复杂度为 O(n) )。
代码

#include <cstdio>
#include <algorithm>
#define maxn 25000005
inline void read(int& x)
{   char c=getchar();x=0;int y=1;
    while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    x*=y;
}
long long A,B,C;
int n,m,sum,now,mod,Q,X[maxn],T[maxn];
bool ok[5005][5005],flag;
int main()
{   read(now);scanf("%lld%lld%lld",&A,&B,&C);read(mod);
    register int i,j,k;int x=0,y=0;
    read(n);read(m);read(Q);sum=n*m;
    for(i=1;i<=sum;++i)
    {   now=(A*now*now%mod+B*now%mod+C)%mod;
        X[i]=now;T[i]=i;
    }
    for(i=1;i<=sum;++i) std::swap(T[i],T[X[i]%i+1]);
    for(i=1;i<=Q;++i) read(x),read(y),std::swap(T[x],T[y]);
    for(i=1;i<=sum;++i) X[T[i]]=i;int tmp=n+m-1;
    for(i=1;i<=sum;++i)
    {   int t1=(X[i]-1)/m+1,t2=X[i]-(t1-1)*m;
        if(ok[t1][t2]) continue;
        if(!flag) printf("%d",i),flag=1;
        else printf(" %d",i);
        ok[t1][t2]=1;--tmp;
        for(j=t1-1;j>=1;--j)
        {   if(ok[j][t2+1]) break;
            for(int k=t2+1;k<=m;++k)
            {   if(ok[j][k]) break;
                ok[j][k]=1;
            }
        }
        for(j=t1+1;j<=n;++j)
        {   if(ok[j][t2-1]) break;
            for(k=t2-1;k>=1;--k)
            {   if(ok[j][k]) break;
                ok[j][k]=1;
            }
        }
        if(!tmp) break;
    }
    return 0;
}

Last round

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值