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]);
    }
    
    

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

  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/LoLiK/p/9750606.html
Copyright © 2011-2022 走看看