• BZOJ3671 [Noi2014]随机数生成器 【贪心】


    题目链接

    BZOJ3671

    题解

    模拟题意生成矩阵贪心从小选择即可
    每选择一个,就标记其左下右上矩阵
    由于每次都是标记一个到边界的矩阵,所以一旦遇到标记过就直接退出即可,可以保证复杂度
    还有就是空间和时间有点卡

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    #define res register
    using namespace std;
    const int maxn = 5005,maxm = 25000005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    inline void write(int x){
    	if (x / 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    LL x,a,b,c,d;
    int n,m,K,Q,A[maxm],ans[maxn << 1],pos[maxm];
    bool vis[maxn][maxn];
    int main(){
    	x = read(); a = read(); b = read(); c = read(); d = read();
    	n = read(); m = read(); Q = read(); K = n * m;
    	for (res int i = 1; i <= K; i++){
    		*(A + i) = i;
    		x = ((a * x + b) * x + c) % d;
    		swap(*(A + i),*(A + x % i + 1));
    	}
    	while (Q--) swap(*(A + read()),*(A + read()));
    	for (res int i = 1; i <= K; i++) *(pos + *(A + i)) = i;
    	res int cnt = 0,E = n + m,x,y;
    	for (res int i = 1; i <= K && cnt < E; i++){
    		if (*(pos + i) % m == 0){
    			x = *(pos + i) / m;
    			y = m;
    		}
    		else {
    			x = *(pos + i) / m + 1;
    			y = *(pos + i) % m;
    		}
    		if (!*(*(vis + x) + y)){
    			ans[++cnt] = i;
    			if (y < m) for (res int j = x - 1; j; j--){
    				if (*(*(vis + j) + y + 1)) break;
    				for (res int k = y + 1; k <= m; k++){
    					if (*(*(vis + j) + k)) break;
    					*(*(vis + j) + k) = true;
    				}
    			}
    			if (y > 1) for (res int j = x + 1; j <= n; j++){
    				if (*(*(vis + j) + y - 1)) break;
    				for (res int k = y - 1; k; k--){
    					if (*(*(vis + j) + k)) break;
    					*(*(vis + j) + k) = true;
    				}
    			}
    		}
    	}
    	for (res int i = 1; i < E; i++) write(*(ans + i)),putchar(' ');
    	return 0;
    }
    
    
  • 相关阅读:
    JS数组去重
    正则表达式验证邮箱手机号等
    js中的事件委托
    c++刷题(6/100)最长上升子序列
    c++刷题(3/100)数独,栈和队列
    在express中HMR(合并express和webpack-dev-server)
    面试整理(3)js事件委托
    面试整理(2)跨域:jsonp与CORS
    面试整理(1):原生ajax
    styled-components真的好吗?
  • 原文地址:https://www.cnblogs.com/Mychael/p/9059700.html
Copyright © 2020-2023  润新知