zoukankan      html  css  js  c++  java
  • 机房测试10.7

    题解之前

    今天是三体的题目背景,比什么美好的每一天好理解多了。

    水滴


    难得的NOIP模拟题,滑窗解决。
    也可以二分区间长度,再进行统计。

    我的(nlogn)算法

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<ctime>
    #define FN "drop"
    
    const int maxn=2e5+5;
    int dan[maxn];
    int cnt[maxn];
    int need[maxn];
    int n,k,R;
    
    bool check(int len) {
    	memset(cnt,0,sizeof cnt);
    	int res=R;
    	for(int i=1;i<=len;i++) {
    		cnt[dan[i]]++;
    		if(cnt[dan[i]]==need[dan[i]]) --res;
    		if(!res) return true;
    	}
    	for(int l=2,r=len+1;r<=n;l++,r++) {
    		--cnt[dan[l-1]];
    		if(cnt[dan[l-1]]==need[dan[l-1]]-1) ++res;
    		++cnt[dan[r]];
    		if(cnt[dan[r]]==need[dan[r]]) --res;
    		if(!res) return true;
    	}
    	return false;
    }
    
    int main() {
    	freopen(FN".in","r",stdin);
    	freopen(FN".out","w",stdout);
    	int T;scanf("%d",&T);
    	while(T--) {
    		memset(need,0,sizeof need);
    		memset(dan,0,sizeof dan);
    		scanf("%d%d%d",&n,&k,&R);
    		for(int i=1;i<=n;i++) scanf("%d",dan+i);
    		for(int i=1;i<=R;i++) {
    			int c,num;scanf("%d%d",&c,&num);
    			need[c]=num;
    		}
    		int l=0,r=n+1,ans=-1;
    		while(l<r) {
    			int mid=l+r>>1;
    			if(check(mid)) {
    				ans=mid;
    				r=mid;
    			}
    			else l=mid+1;
    		}
    		if(!~ans) printf("DESTROY ALL
    ");
    		else  printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    std的O(n)算法

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int MAXN = 200000;
    int D[MAXN + 5], ned[MAXN + 5];
    int tot[MAXN + 5], nw[MAXN + 5];
    void solve() {
    	int N, K, R;
    	scanf("%d%d%d", &N, &K, &R);
    	for(int i=0;i<K;i++)
    		ned[i] = tot[i] = 0;
    	for(int i=1;i<=N;i++) {
    		scanf("%d", &D[i]);
    		tot[D[i]]++;
    	}
    	for(int i=1;i<=R;i++) {
    		int B, Q;
    		scanf("%d%d", &B, &Q);
    		ned[B] = Q;
    	}
    	for(int i=0;i<K;i++)
    		if( tot[i] < ned[i] ) {
    			puts("DESTROY ALL");
    			return ;
    		}
    	int ans = N, re = R, le = 1, ri = 0;
    	while( le <= N ) {
    		while( ri + 1 <= N && re ) {
    			nw[D[++ri]]++;
    			if( nw[D[ri]] == ned[D[ri]] )
    				re--;
    		}
    		if( !re ) ans = min(ans, ri-le+1);
    		if( nw[D[le]] == ned[D[le]] ) re++;
    		nw[D[le++]]--;
    	}
    	printf("%d
    ", ans);
    }
    int main() {
    	freopen("drop.in", "r", stdin);
    	freopen("drop.out", "w", stdout);
    	int T;
    	scanf("%d", &T);
    	for(int i=1;i<=T;i++)
    		solve();
    }
    

    “神“


    2-SAT裸题?

    一眼看出来2-SAT,边都连好了,写不来算法。

    太菜了。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int MAXN = 5000;
    struct edge{
    	int to;
    	edge *nxt;
    }edges[2*MAXN + 5], *adj[MAXN + 5], *ecnt=&edges[0];
    void addedge(int u, int v) {
    	edge *p = (++ecnt);
    	p->to = v, p->nxt = adj[u], adj[u] = p;
    }
    void init() {
    	ecnt = &edges[0];
    	for(int i=0;i<=MAXN;i++)
    		adj[i] = NULL;
    }
    bool vis[MAXN + 5];
    void dfs(int x) {
    	vis[x] = true;
    	for(edge *p=adj[x];p!=NULL;p=p->nxt)
    		if( !vis[p->to] ) dfs(p->to);
    }
    void solve() {
    	init(); int N, M;
    	scanf("%d%d", &N, &M);
    	for(int i=1;i<=M;i++) {
    		int u, v;
    		scanf("%d%d", &u, &v);
    		if( u < 0 )
    			u = (-u-1)<<1|1;
    		else u = (u-1)<<1;
    		if( v < 0 )
    			v = (-v-1)<<1|1;
    		else v = (v-1)<<1;
    		addedge(u, v^1);
    		addedge(v, u^1);
    	}
    	int ans = 3;
    	for(int i=0;i<N;i++) {
    		bool f1 = false, f2 = false, f3 = false;
    		for(int j=0;j<(N<<1);j++)
    			vis[j] = false;
    		dfs(i<<1);
    		f1 = vis[i<<1|1];
    		for(int j=0;j<(N<<1);j++)
    			vis[j] = false;
    		dfs(i<<1|1);
    		f2 = vis[i<<1];
    		for(int j=0;j<N;j++)
    			f3 = f3 || vis[j<<1];
    		if( f1 && f2 ) ans = min(ans, 0);
    		else if( f2 ) ans = min(ans, 1);
    		else if( f3 ) {
    			if( f1 ) ans = min(ans, 1);
    			else ans = min(ans, 2);
    		}
    	}
    	if( ans == 3 ) puts("No Way");
    	else printf("%d
    ", ans);
    }
    int main() {
    	freopen("god.in", "r", stdin);
    	freopen("god.out", "w", stdout);
    	int T;
    	scanf("%d", &T);
    	for(int i=1;i<=T;i++)
    		solve();
    }
    

    执剑人


    贪心+数据结构。

    只会贪心,于是只有60分。

    用后缀和来选出枪毙名单。
    用栈存从一边开始的枪毙名单,线段树从另外一边开始操作。

    #include<cstdio>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int INF = (1<<30);
    const int MAXN = 500000;
    struct query{
    	int ri, ind;
    	query(int _r, int _i):ri(_r), ind(_i){}
    };
    vector<query>qry[MAXN + 5];
    char str[MAXN + 5];
    int stk[MAXN + 5], ans[MAXN + 5], top;
    struct node{
    	int mss, sum;
    	int le, ri;
    }tree[4*MAXN + 5];
    void PushUp(int x) {
    	tree[x].mss = min(tree[x<<1|1].mss, tree[x<<1].mss + tree[x<<1|1].sum);
    	tree[x].sum = tree[x<<1].sum + tree[x<<1|1].sum;
    }
    void Build(int x, int l, int r) {
    	tree[x].le = l, tree[x].ri = r;
    	if( l == r ) {
    		tree[x].mss = tree[x].sum = 0;
    		return ;
    	}
    	int mid = (l + r) >> 1;
    	Build(x<<1, l, mid);
    	Build(x<<1|1, mid+1, r);
    	PushUp(x);
    }
    void Modify(int x, int pos, int key) {
    	if( pos > tree[x].ri || pos < tree[x].le )
    		return ;
    	if( tree[x].le == tree[x].ri ) {
    		tree[x].sum = tree[x].mss = key;
    		return ;
    	}
    	Modify(x<<1, pos, key);
    	Modify(x<<1|1, pos, key);
    	PushUp(x);
    }
    node Query(int x, int pos) {
    	if( tree[x].ri <= pos )
    		return tree[x];
    	int mid = (tree[x].le + tree[x].ri) >> 1;
    	if( pos <= mid )
    		return Query(x<<1, pos);
    	else {
    		node ret = Query(x<<1|1, pos);
    		ret.mss = min(ret.mss, ret.sum + tree[x<<1].mss);
    		ret.sum = ret.sum + tree[x<<1].sum;
    		return ret;
    	}
    }
    inline int Read() {
    	char ch = getchar(); int x = 0, f = 1;
    	while( (ch > '9' || ch < '0') && ch != '-' ) ch = getchar();
    	if( ch == '-' ) f = -1, ch = getchar();
    	while( '0' <= ch && ch <= '9' )
    		x = 10*x + ch-'0', ch = getchar();
    	return x * f;
    }
    int main() {
    	freopen("sworder.in", "r", stdin);
    	freopen("sworder.out", "w", stdout);
    	int N, Q;
    	scanf("%d%s%d", &N, str+1, &Q);
    	for(int i=1;i<=Q;i++) {
    		int l, r;
    		l = Read(), r = Read();
    		qry[l].push_back(query(r, i));
    	}
    	Build(1, 1, N); top = N+1;
    	for(int i=N;i>=1;i--) {
    		if( str[i] == 'C' )
    			stk[--top] = i;
    		else {
    			if( top != N+1 ) {
    				Modify(1, stk[top], -1);
    				stk[top++] = 0;
    			}
    			Modify(1, i, 1);
    		}
    		for(int j=0;j<qry[i].size();j++) {
    			int p = upper_bound(stk+top, stk+N+1, qry[i][j].ri) - stk;
    			ans[qry[i][j].ind] = (p-top) - min(0, Query(1, qry[i][j].ri).mss);
    		}
    	}
    	for(int i=1;i<=Q;i++)
    		printf("%d
    ", ans[i]);
    }
    
    

    于是今天愉快地拿到了大众分数。

  • 相关阅读:
    javascript插入样式
    Backbone.js使用jsonp api示例
    RequireJS optimizer Ant task
    Javascript 中的 call 和 apply
    通过shtml实现重构页面模块化构建的相关设置
    Eclipse 支持JQuery提示 jQueryWTP插件的安装方法
    iframe加载完成监控兼容IE/FF/Chrome
    让浏览器跨域
    Javascript 类的实现
    宏定义和内联函数区别
  • 原文地址:https://www.cnblogs.com/LoLiK/p/9750606.html
Copyright © 2011-2022 走看看