ZOJ 3705 3706 3708 3710 3712 3713 3714(水题)

第一次参加省赛,能做的竟然都是水题,还是太弱了.

3705 给出一些计分规则,最后排序输出结果,表示这题严重歧视男性.

#include <cstdio>
#include <map>
#include <memory.h>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 501;
struct app{
	char name[50];
	double pts;
	bool operator<(const app & rhs)const{
		return pts > rhs.pts ||(pts == rhs.pts && name < rhs.name);
	}
}apps[maxn];
map<string, int> rank;
map<int,int> probSet;
bool isP[10000];
int japanJam[1001], N, M;

void init(){
	memset(isP + 2, 1, sizeof(isP));
	for(int i = 2; i < 10000; ++i){
		if(isP[i])
			for(int j = 2; j * i < 10000; ++j){
				isP[i * j] = 0;
			}
	}
}
int main(){
	init();
	int T;
	scanf("%d", &T);
	while(T--){
		rank.clear();
		probSet.clear();
		memset(apps, 0, sizeof(apps));
		scanf("%d %d", &N, &M);
		int MaoMaoN;
		scanf("%d", &MaoMaoN);
		for(int i = 0; i < MaoMaoN; ++i){
			int t;
			scanf("%d", &t);
			probSet[t] = 1;
		}
		int OSCN;
		scanf("%d", &OSCN);
		for(int i = 0; i < OSCN; ++i){
			int t;
			scanf("%d", &t);
			probSet[t] = 2;
		}
		int compN;
		scanf("%d", &compN);
		for(int i = 0; i < compN; ++i){
			char name[50];
			int  r;
			scanf("%s %d", name, &r);
			rank[name] = r;
		}
		for(int i = 0; i < N; ++i){
			char name[50], teamName[50], gender[50];
			int  proN, jam;
			scanf("%s %s %s %d %d", name, teamName, gender, &proN, &jam);
			memcpy(apps[i].name, name, sizeof(name));
			for(int j = 0; j < proN; ++j){
				int t;
				scanf("%d", &t);
				if(probSet[t] == 1){
					apps[i].pts += 2.5;
				}else if(probSet[t] == 2){
					apps[i].pts += 1.5;
				}else if(isP[t]){
					apps[i].pts += 1;
				}else{
					apps[i].pts += 0.3;
				}
			}
			for(int j = 0; j < jam; ++j){
				scanf("%d", &japanJam[j]);
			}
			if(jam >= 3){
				sort(japanJam, japanJam + jam, greater<int>());
				if(japanJam[2] - 1200 > 0){
					apps[i].pts += (japanJam[2] - 1200) / 100.0 * 1.5;
				}
			}
			if(rank[teamName] == 1){
				apps[i].pts += 36;
			}else if(rank[teamName] == 2){
				apps[i].pts += 27;
			}else if(rank[teamName] == 3){
				apps[i].pts += 18;
			}
			if(gender[0] == 'F'){//女生+33分
				apps[i].pts += 33;
			}
		}
		sort(apps, apps + N);
		for(int i = 0; i < M; ++i){
			printf("%s %.3lf\n", apps[i].name, apps[i].pts);
		}
	}

	return 0;
}


3706 把两个砝码任意一个分成两份,求最多能称量的重量总数,数据量很小,直接暴力枚举.

#include <cstdio>
#include <memory.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 201;
bool vis[maxn];
int weih[3];
int x, y;
int func(int x, int y){
	int maxv = 0;
	for(int i = 1; i < x; ++i){
		weih[0] = x - i, weih[1] = i, weih[2] = y;
		int cnt = 0;
		sort(weih, weih + 3, greater<int>());
		memset(vis, 0 , sizeof(vis));
		int &a = weih[0], &b = weih[1], &c = weih[2];
		if(a > 0 && !vis[a]){
			vis[a] = 1;
			cnt++;
		}
		if(b > 0 && !vis[b]){
			vis[b] = 1;
			cnt++;
		}
		if(c > 0 && !vis[c]){
			vis[c] = 1;
			cnt++;
		}
		if(a - b > 0 && !vis[a - b]){
			vis[a - b] = 1;
			cnt++;
		}
		if(a + b > 0 && !vis[a + b]){
			vis[a + b] = 1;
			cnt++;
		}
		if(a - c > 0 && !vis[a - c]){
			vis[a - c] = 1;
			cnt++;
		}
		if(a + c > 0 && !vis[a + c]){
			vis[a + c] = 1;
			cnt++;
		}
		if(b + c > 0 && !vis[b + c]){
			vis[b + c] = 1;
			cnt++;
		}
		if(b - c > 0 && !vis[b - c]){
			vis[b - c] = 1;
			cnt++;
		}
		if(a + b + c > 0 && !vis[a + b + c]){
			vis[a + b + c] = 1;
			cnt++;
		}
		if(a + b - c > 0 && !vis[a + b - c]){
			vis[a + b - c] = 1;
			cnt++;
		}
		if(a - b - c > 0 && !vis[a - b - c]){
			vis[a - b - c] = 1;
			cnt++;
		}
		if(a - b + c > 0 && !vis[a - b + c]){
			vis[a - b + c] = 1;
			cnt++;
		}
		maxv = max(maxv, cnt);
	}
	return maxv;
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d %d", &x, &y);
		int ans = 0;
		ans = max(ans, func(x, y));
		ans = max(ans, func(y, x));
		printf("%d\n", ans);
	}
	return 0;
}

3708 给出一个图,求出边和点之间的比率,直接把重复边去掉,除一下就是结果了...

#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int maxn = 501;
bool vis[maxn][maxn];

int  se[maxn], ee[maxn], n, m;
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		memset(vis, 0 , sizeof(vis));
		scanf("%d %d", &n, &m);
		int ecnt = m;
		for(int i = 0; i < m; ++i){
			scanf("%d", &se[i]);
		}
		for(int i = 0; i < m; ++i){
			scanf("%d", &ee[i]);
		}
		for(int i = 0; i < m; ++i){
			if(!vis[se[i]][ee[i]]){
				vis[se[i]][ee[i]] = vis[ee[i]][se[i]] = 1;
			}else{
				ecnt --;
			}
		}
		printf("%.3lf\n", (double)ecnt / n);
	}
	return 0;
}


3710 给出一个朋友关系图,如果两个人拥有超过k个共同朋友,那么几天后他们就能成为朋友,求经过足够的时间后,最多能行成多少新的朋友关系,要注意的是直到不能再建立新朋友关系为止,直接暴力.

#include <iostream>
#include <memory.h>
#include <cstdio>
using namespace std;
const int maxn = 101;
bool g[maxn][maxn];
int n, m, k;
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%d %d %d", &n, &m, &k);
		memset(g, 0, sizeof(g));
		int ans = 0;
		for(int i = 0; i < m; ++i){
			int u, v;
			scanf("%d %d", &u, &v);
			g[u][v] = g[v][u] = 1;
		}
		while(1){
			int t = 0;
			for(int i = 0; i < n; ++i){
				for(int j = 0; j < n; ++j){
					if(!g[i][j] && i != j){//还不是朋友
						int sum = 0;
						for(int k = 0; k < n; ++k){
							if(g[i][k] && g[j][k]){
								sum++;//累计共同朋友
							}
						}
						if(sum >= k){
							t++;
							g[i][j] = g[j][i] = 1;
						}
					}
				}
			}
			if(!t)break;
			ans += t;
		}
		printf("%d\n",ans);
	}
	return 0;
}



3712 基本上读懂题目已经就能做出来,因为连击是连续的,所以从50到300累加肯定是最大的得分,从300到50累加肯定是最小的得分,

#include <stdio.h>
int sc[3];
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d %d %d", &sc[0], &sc[1], &sc[2]);
		int minAns = 0, maxAns = 0, combo = 1;
		for(int i = 2; i >= 0; --i){
			int p = 0;
			if(i == 2)p = 50;
			else if(i == 1) p = 100;
			else p = 300; 
			for(int j = 0; j < sc[i]; ++j){
				maxAns += p * ((combo - 1) * 2 + 1); 
				combo++;
			}
		}
		combo = 1;
		for(int i = 0; i < 3; ++i){
			int p = 0;
			if(i == 2)p = 50;
			else if(i == 1) p = 100;
			else p = 300; 
			for(int j = 0; j < sc[i]; ++j){
				minAns += p * ((combo - 1) * 2 + 1); 
				combo++;
			}
		}
		printf("%d %d\n",minAns, maxAns);
	}
	return 0;
}

3713 意思是把一行字符串的长度按照找7位一个字节输出,如果长度能够存在7位里,字节的最高位置0,否则只输出7位并且输出字节的最高位置1,直到全部输出长度.

要注意的是有空串要输出00,其他按照16进制输出就可以了,注意要补0.

#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int maxn = 3000050 ;
char str[maxn];

int main(){
	int T;
	scanf("%d", &T);
	getchar();
	while(T--){
		gets(str);
		int len = strlen(str);
		int tlen = len;
		if(len == 0){
			printf("00");
		}
		while(tlen){
			int content = tlen & 0x7F;
			tlen = tlen >> 7;
			if(tlen > 0)content |= 0X80;
			printf("%02X", content);
		}
		for(int i = 0; i < len; ++i){
			printf("%02X",str[i]);
		}
		printf("\n");
	}
	return 0;
}

3715 给出一行数字,求出最大的M个连续数字,首尾向连,开场3分钟不到就有4个过了.

#include <cstdio>
#include <iostream>
#include <memory.h>
using namespace std;
const int maxn = 201 * 2;
int cdi[maxn],N, M;

int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d %d", &N, &M);
		for(int i = 0; i < N; ++i){
			scanf("%d", &cdi[i]);
		}
		memcpy(cdi + N, cdi, N * sizeof(int));
		int ans = 0;
		for(int i = 0; i <N; ++i){
			int sum = 0;
			for(int j = 0; j < M; ++j){
				sum += cdi[i + j];
			}
			ans = max(ans, sum);
		}
		printf("%d\n", ans);
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值