The 10th Zhejiang Provincial Collegiate Programming Contest 蒻菜的水题题解。

http://acm.zju.edu.cn/onlinejudge/contestInfo.do?contestId=347

今天参加了今年的浙江省赛网络同步赛(?),被虐得很惨。。。

做了五道水题只A掉四道,表示压力很大。

蒻蒻地发个水题的题解。。。勿喷


A

一来就是神题,被老长的英文题目吓了一跳。。。

所以就跳过。。。


B

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3706

据说是水题,很多人切掉了,我是留在最后做的,但做了之后WA了,后面懒得做了(因为肚子饿了)

数据就到100,完全可以暴力解决的。但蒻菜却WA了伤不起。。。


C

神题不会做。。。


D

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3708

水题。

刚开始被那张错综复杂的拓扑图吓唬的不敢做,后来认真看之后发现其实是大水题。。。

题目要求读入一排弧的顶点和另一排一排对应的终点,然后算出网络密度,网络密度被定义为弧的数量和点的数量之间的比率。

题目说这图是无向图,只要开两个数组放开端和起点,再开一个bool型的二维数组,一个一个标记,如果发现之前标记过的就把输入的弧数-1,最后再输出密度。

#include<cstdio>
#define MAXN 510

int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int n, m;
		int s[MAXN], e[MAXN];
		bool map[MAXN][MAXN] = {0};
		scanf("%d%d", &n, &m);
		int cnt = m;
		for (int i = 0; i < m; i++)
			scanf("%d", &s[i]);
		for (int i = 0; i < m; i++)
			scanf("%d", &e[i]);
		for (int i = 0; i < m; i++)
			if (!map[s[i]][e[i]] && !map[e[i]][s[i]])
				map[s[i]][e[i]] = map[e[i]][s[i]] = true;
			else
				cnt--;
		printf("%.3f\n", (double) cnt / (double) n);
	}
	return 0;
}


E

egg painting,蛋的画,为什么我觉得看起来像egg pain呢。。。

神题不会做。。。


F

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3710

水题。

题意:输入现有朋友关系图,然后给一个k,如果两个人有相同的k个朋友的话就建立新朋友关系,最后输出新建立的朋友关系的个数。

难度在如何判断有几个相同的基友,本菜实在想不到好的方法,就使用set来计算,构造set数组存放那个人的朋友,然后循环两两判断是否为朋友。计算方法为:做一个sum的set放两个人的朋友的集合,用两个set的个数和-sum的个数=重复的朋友。

不过思路是还好,就是set貌似没有合并的函数,很郁闷,于是用iterator来遍历两个set插到sum里面。

做出来后交上去结果超时了,于是改用构造时进行复制替换其中一个set的复制,时间2s我1.6s过了。。。

(人家用矩阵算出朋友的个数再判断,200ms,我1620ms弱爆了!!!跪跪跪,见http://blog.csdn.net/qq909157370/article/details/8916959

#include<cstdio>
#include<set>
using namespace std;
#define MAXN 2000

int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int n, m, k, a, b;
		set <int> s[MAXN];
		scanf("%d%d%d", &n, &m, &k);
		for (int i = 0; i < m; i++)
		{
			scanf("%d%d", &a, &b);
			s[a].insert(b);
			s[b].insert(a);
		}
		bool flag = 1;
		int cnt = 0;
		while (flag)
		{
			flag = false;
			for (int i = 0; i < n; i++)
				for (int j = i + 1; j < n; j++)
				{
					if (s[i].count(j) != 0)
						continue;
					set <int> sum (s[i]);
					/*******************************替换掉
					for (set<int>::iterator y = s[i].begin(); y != s[i].end(); y++)
						sum.insert(*y);
					******************/
					for (set<int>::iterator y = s[j].begin(); y != s[j].end(); y++)
						sum.insert(*y);
					if (s[i].size() + s[j].size() - sum.size() >= k)
					{
						s[i].insert(j);
						s[j].insert(i);
						cnt++;
						flag = true;
					}
				}
		}
		printf("%d\n", cnt);
	}
	return 0;
}


G

神题,只有4人A了。。。

剁手啊,好吓人。。。

H

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3712

大水题。
一打开题目就发现熟悉的画面,osu!。。。

老早就听说各神牛都在玩osu,这次这么嚣张在省赛上赛成绩。

大触手啊,近3000万分让我这菜鸟情何以堪。。。

扯太远了。

题目理解之后发现非常水。说是贪心呢,又太简单了。

题意:给300分的点击数,100分的点击数,50分的点击数,然后告诉你这是连击的,而且每次点击得到的分数和连击数有关,求可能得到的最小分数和最大分数。分数计算:P = Point * (Combo * 2 + 1)

很明显连击数越高分数翻倍越高,那么最小就是300-100-50这样的打,最大就是倒过来打。

用六个循环搞定。(代码很挫)

#include<cstdio>
#define MAXN 2000

int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int p3, p1, p5, cnt = 0;
		long long min = 0, max = 0;
		scanf("%d%d%d", &p3, &p1, &p5);
		for (int i = 0; i < p3; i++)
			min += 300 * ((cnt++) * 2 + 1);
		for (int i = 0; i < p1; i++)
			min += 100 * ((cnt++) * 2 + 1);
		for (int i = 0; i < p5; i++)
			min += 50 * ((cnt++) * 2 + 1);
		printf("%lld ", min);
		cnt = 0;
		for (int i = 0; i < p5; i++)
			max += 50 * ((cnt++) * 2 + 1);
		for (int i = 0; i < p1; i++)
			max += 100 * ((cnt++) * 2 + 1);
		for (int i = 0; i < p3; i++)
			max += 300 * ((cnt++) * 2 + 1);
		printf("%lld\n", max);
	}
	return 0;
}


I

神题。

其实我没看题目。。。


J

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3714

大水题。

题目说坐成一圈我还以为是约瑟夫环,结果一点关系都没有。

开场5分钟就有神牛把它秒掉了,orz。。。

蒻菜看了好久才看懂,还调了半天,给神牛们跪了。。。

题意:坐成一圈,连续地取M个数的和,求最大和。

思路:暴力。数组存入数,在数组后面加上前M个数,两个循环求和取最大值。

#include<cstdio>

int main()
{
	int n, a, b, i, num[3000], tmp, max;
	scanf("%d", &n);
	while (n--)
	{
		scanf("%d%d", &a, &b);
		max = 0;
		for (i = 1; i <= a; i++)
			scanf("%d", &num[i]);
		for (; i <= a + b; i++)
			num[i] = num[i - a];
		for (i = 1; i <= a; i++)
		{
			tmp = 0;
			for (int j = 0; j < b; j++)
				tmp += num[i + j];
			if (max < tmp)
				max = tmp;
		}
		printf("%d\n", max);
	}
	return 0;
}



K

神题。

菜B没有看,看不懂,不会做。


唔。。。总之就是这样,这次比赛就刷了几题水题,难题都束手无策,看来还需努力啊。。。

苣蒻给虐全场的大神们跪碎了。。。

原文地址:https://www.cnblogs.com/java20130723/p/3212163.html