• 20/08/01测试


    T1

    考场上的想法:

    只有(0)(1)两种状态,可以二进制压缩。挺好的。

    数据范围不大,可以搜索,但是肯定会炸。蒟蒻害怕。

    而目标状态和起始状态都是给定的,可以用双端搜索优化。

    感觉双端搜索是正解,然而之前打的很少,就只能自己yy了。

    yy了好长时间终于yy出来了,但用的时间有点长,导致其他题的暴力分没拿到。

    最可恨的是因为搜索时少判了情况丢了(20)分。其实考试时想到了但懒得改qaq

    考场代码
    
    

    include <bits/stdc++.h>

    using namespace std;

    const int maxn = 20;

    int n, m, vis[2][1<<12], dis[2][1<<12];

    struct node{
    int val[maxn];
    }e[200];

    void bfs(){
    queue q_start, q_end;
    int qwq[11], qaq = 0;
    for(int i = 1; i <= n; i ++) qwq[i] = 1;
    for(int i = 1; i <= n; i ++) if(qwq[n-i+1]) qaq += 1<<(i-1);
    q_start.push(qaq), q_end.push(0);
    vis[0][qaq] = 1, vis[1][0] = 1;
    while(q_start.size() or q_end.size()){
    if(1 or 1 or 1 or 1){
    int now = q_start.front();
    q_start.pop();
    int cnt = 0, cmp = now, a[11], tmp[11];
    memset(tmp, 0, sizeof(tmp));
    while(cmp){
    tmp[++cnt] = cmp&1;
    cmp >>= 1;
    }
    for(int i = 1; i <= n; i ++) a[i] = tmp[n-i+1];
    int b[11];
    for(int i = 1; i <= m; i ++){
    for(int j = 1; j <= n; j ++){
    if(e[i].val[j] ==-1) b[j] = 1;
    if(e[i].val[j] == 1) b[j] = 0;
    if(e[i].val[j] == 0) b[j] = a[j];
    }
    int turned = 0;
    for(int i = 1; i <= n; i ++) if(b[n-i+1]) turned += 1<<(i-1);
    if(!vis[0][turned]){
    q_start.push(turned);
    vis[0][turned] = 1;
    dis[0][turned] = dis[0][now] + 1;
    }
    if(vis[1][turned]){
    printf("%d ", dis[0][turned]+dis[1][turned]);
    return;
    }
    }
    }
    if(1 or 1 or 1 or 1){
    int now = q_end.front();
    q_end.pop();
    int cnt = 0, cmp = now, a[11], tmp[11];
    memset(tmp, 0, sizeof(tmp));
    while(cmp){
    tmp[++cnt] = cmp&1;
    cmp >>= 1;
    }
    for(int i = 1; i <= n; i ++) a[i] = tmp[n-i+1];
    int b[11];
    for(int i = 1; i <= m; i ++){
    for(int j = 1; j <= n; j ++){
    if((e[i].val[j] ==-1 and !b[j])or(e[i].val[j] == 1 and b[j])) continue;
    if(e[i].val[j] ==-1) b[j] = 0;
    if(e[i].val[j] == 1) b[j] = 1;
    if(e[i].val[j] == 0) b[j] = a[j];
    }
    int turned = 0;
    for(int i = 1; i <= n; i ++) if(b[n-i+1]) turned += 1<<(i-1);
    if(!vis[1][turned]){
    q_end.push(turned);
    vis[1][turned] = 1;
    dis[1][turned] = dis[1][now] + 1;
    }
    if(vis[0][turned]){
    printf("%d ", dis[0][turned]+dis[1][turned]);
    return;
    }
    }
    }
    }
    printf("-1 ");
    return;
    }

    signed main(){
    freopen("flame.in", "r", stdin);
    freopen("flame.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i ++){
    for(int j = 1; j <= n; j ++){
    scanf("%d", &e[i].val[j]);
    }
    }
    bfs();
    return 0;
    }

    嘶,完了考试时把这道题想难了,数据太水,压根不用双端搜索,直接从一端bfs就行啊啊啊啊啊啊。

    结果跑双端搜索还少判了情况丢了(20)分qaq。还花了好长时间导致其他题暴力分没拿!嘶,难受qaq。

    想给出题人YY学长寄刀片过去。

    思路:二进制压缩+搜索

    超级简单,因为这道题丢了(20+)的分数心情不好不想写了qaq。

    啊其实是我自己的问题,跟YY学长无关,发发牢骚而已,还是我自己没把控好时间的分配,怪我太菜了。蒟蒻反思orz

    代码
    
    
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 20;
    
    int n, m, vis[1<<12], dis[1<<12];
    
    struct node{
    	int val[maxn];
    }e[200];
    
    void bfs(){
    	queue<int> q;
    	int qwq[11], qaq = 0;
    	for(int i = 1; i <= n; i ++) qwq[i] = 1;
    	for(int i = 1; i <= n; i ++) if(qwq[n-i+1]) qaq += 1<<(i-1);
    	q.push(qaq);
    	vis[qaq] = 1; 
    	while(q.size()){
    		int now = q.front();
    		q.pop();
    		int cnt = 0, cmp = now, a[11], tmp[11];
    		memset(tmp, 0, sizeof(tmp));
    		while(cmp){
    			tmp[++cnt] = cmp&1;
    			cmp >>= 1;
    		}
    		for(int i = 1; i <= n; i ++) a[i] = tmp[n-i+1];
    		int b[11];
    		for(int i = 1; i <= m; i ++){
    			for(int j = 1; j <= n; j ++){
    				if(e[i].val[j] ==-1) b[j] = 1;
    				if(e[i].val[j] == 1) b[j] = 0;
    				if(e[i].val[j] == 0) b[j] = a[j];
    			}
    			int turned = 0;
    			for(int i = 1; i <= n; i ++) if(b[n-i+1]) turned += 1<<(i-1);
    			if(!vis[turned]){
    				q.push(turned);
    				vis[turned] = 1;
    				dis[turned] = dis[now] + 1;
    			}
    		}
    	}
    	printf("-1
    ");
    	return;
    }
    
    signed main(){
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= m; i ++){
    		for(int j = 1; j <= n; j ++){
    			scanf("%d", &e[i].val[j]); 
    		}
    	}
    	bfs();
    	return 0;
    }
    

    T2

    贪心。考试时划水了没时间写了,最后二十分钟写了个残缺的搜索没调出来。

    code
    
    
    #include <bits/stdc++.h>
    using namespace std;
    
    long long read(){
    	long long s = 0, f = 1; char ch;
    	while(!isdigit(ch = getchar())) (ch == '-') and (f = -f);
    	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
    	return s * f;
    }
    
    const int maxn = 1005;
    
    int n, m, high, wid, ans, cnt, tot, flag, vis[maxn], c[maxn];
    
    struct people{
    	int h, w, der;
    }a[maxn];
    
    int cmp(int a, int b){
    	return a > b;
    }
    
    signed main(){
    	freopen("photo.in", "r", stdin);
    	freopen("photo.out", "w", stdout);
    	n = read(); m = n/2;
    	for(int i = 1;i <= n; i ++){
    		a[i].w = read(), a[i].h = read();
    	}
    	ans = 1e9;
    	for(int high = 1; high <= 1000; high ++){
    		cnt = 0, tot = 0, flag = 0, wid = 0;
    		memset(c, 0, sizeof(c));
    		for(int i = 1; i <= n; i ++) {
    			if(a[i].h > high and a[i].w > high){
    				flag = 1; break;
    			}
    			if(a[i].h > high and a[i].w <= high){
    				++ cnt; wid += a[i].h;
    			}
    			if(a[i].h <= high and a[i].w > high){
    				wid += a[i].w;
    			}
    			if(a[i].h <= high and a[i].w <= high){
    				if(a[i].h < a[i].w){
    					c[++tot] = a[i].w - a[i].h; wid += a[i].w;
    				}
    				if(a[i].h >= a[i].w){
    					wid += a[i].w;
    				}
    			}
    		}
    		if(flag == 1 or cnt > m) continue;
    		sort(c+1, c+tot+1, cmp);
    		for(int i = 1; i <= m-cnt; i ++) wid -= c[i];
    		ans = min(ans, high*wid);
    	}
    	printf("%d", ans);
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    

    T3

    乱搞。但是别人普遍拿到了30分的暴力分,啊我没拿到orz。主要还是划水了qwq。

    code
    
    
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e6+10;
    
    int n, A, B, C, D, a[5010], b[5010], c[5010], d[5010], maxnn, cur, f[maxn], c1[maxn], c2[maxn], cnt1, cnt2;
    long long ans;
    
    signed main(){
    	freopen("eat.in", "r", stdin);
    	freopen("eat.out", "w", stdout);
    	scanf("%d%d%d%d%d", &n, &A, &B, &C, &D);
    	for(int i = 1; i <= A; i ++) scanf("%d", &a[i]);
    	for(int i = 1; i <= B; i ++) scanf("%d", &b[i]);
    	for(int i = 1; i <= C; i ++) scanf("%d", &c[i]);
    	for(int i = 1; i <= D; i ++) scanf("%d", &d[i]);
    	for(int i = 1; i <= A; i ++){
    		for(int j = 1; j <= B; j++){
    			if(a[i] + b[j] <= n){
    				f[a[i] + b[j]]++;
    				maxnn = max(maxnn, a[i] + b[j]);
    			}
    		}
    	}
    	for(int i = 0; i <= maxnn; i ++){
    		while(f[i]){
    			f[i]--;
    			c1[++cnt1] = i;
    		}
    	}
    	maxnn = 0;
    	for(int i = 1; i <= C; i ++){
    		for(int j = 1; j <= D; j ++){
    			if(c[i] + d[j] <= n) {
    				f[c[i] + d[j]]++;
    				maxnn = max(maxnn, c[i] + d[j]);
    			}
    		}
    	}
    	for(int i = 0; i <= maxnn; i ++){
    		while(f[i]){
    			f[i]--;
    			c2[++cnt2] = i;
    		}
    	}
    	for(cur = cnt2; cur >= 1; cur--){
    		if(c1[1] + c2[cur] <= n){
    			break;
    		}
    	}
    	for(int i = 1; i <= cnt1; i ++){
    		ans += cur;
    		while(cur and c1[i + 1] + c2[cur] > n) cur--;
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

  • 相关阅读:
    20175202 《Java程序设计》第六周学习总结
    2018-2019-2 20175202实验一《Java开发环境的熟悉》实验报告
    20175202 《Java程序设计》迭代和JDB
    20175202 《Java程序设计》第五周学习总结
    20175202 《Java程序设计》第三周学习总结
    20175202 《Java程序设计》第四周学习总结
    第六周学习总结
    java第一次实验
    第五次学习总结
    第四次学习总结
  • 原文地址:https://www.cnblogs.com/Vanyun/p/13413789.html
Copyright © 2020-2023  润新知