Codeforces Round #369 (Div. 2)

原创 2016年08月30日 09:38:44
A. Bus to Udayland
纯水题不说了、
#include<algorithm>
#include<cmath>
#include<stdio.h>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
const int qq = 1e5+10;
string str[qq];
int main(){
	int n;scanf("%d",&n);
	for(int i=0; i<n; ++i)	cin >> str[i];
	int flag = 0;
	for(int i=0; i<n; ++i){
		if(str[i][0]=='O'&&str[i][1]=='O'){
			flag = 1;
			str[i][0] = str[i][1]='+';
			break;
		}
		else if(str[i][3]=='O'&&str[i][4]=='O'){
			flag = 1;
			str[i][4] = str[i][3]='+';
			break;
		}
	}
	if(!flag)	printf("NO\n");
	else{
		printf("YES\n");
		for(int i=0; i<n; ++i)	cout << str[i] << endl;
	}
	return 0;
}


B. Chris and Magic Square
题意:给一个n*n个矩阵,其中有且又只有一个为0,其他全是正整数要求你在0的位置上填上一个正整数是的每行每列以及两条主要的对角线的和都相等
思路:我是先把元素0所在的行和列排开,先判断剩下的行和列以及对角线是否相等,然后把0所在的行和列以及对角线的和加起来填上一个数看是否相等
(注意这题0的位置一定要填上正整数)

#include<algorithm>
#include<cmath>
#include<stdio.h>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
typedef __int64 ll;
const int qq = 505;
ll mar[qq][qq];
ll r[qq],c[qq];
ll zero[5];
int main(){
	int n;scanf("%d",&n);
	if(n==1){
		printf("1\n");
		return 0;
	}
	int tx,ty;
	for(int i=1; i<=n; ++i)
		for(int j=1; j<=n; ++j){
			scanf("%I64d",&mar[i][j]);
			if(mar[i][j]==0)	tx=i,ty=j;
		}
	int flag = 1;
	ll tmp;
	for(int i=1; i<=n; ++i)
		if(i!=tx){
			ll sum = 0;
			for(int j=1; j<=n; ++j)
				sum+=mar[i][j];
			r[i] = sum;
			tmp = r[i];
		}
	for(int i=1; i<=n; ++i)
		if(i!=tx&&r[i]!=tmp)	flag = 0;
	for(int j=1; j<=n; ++j)
		if(j!=ty){
			ll sum = 0;
			for(int i=1; i<=n; ++i)
				sum+=mar[i][j];
			c[j] = sum;
		}
	for(int i=1; i<=n; ++i)
		if(i!=ty&&c[i]!=tmp)	flag = 0;
	ll u;
	if(ty!=tx){
		u = 0;
		for(int i=1; i<=n; ++i)
			u+=mar[i][i];
		if(u!=tmp)	flag = 0;
	}
	if(tx!=n-ty+1){
		u = 0;
		for(int i=1; i<=n; ++i)
			u+=mar[i][n-i+1];
		if(u!=tmp)	flag = 0;
	}
	if(!flag){
		printf("-1\n");
		return 0;
	}
	for(int j=1; j<=n; ++j)
		zero[0]+=mar[tx][j];
	for(int i=1; i<=n; ++i)
		zero[1]+=mar[i][ty];
	int k=2;
	if(tx==ty){
		for(int i=1; i<=n; ++i)
			zero[k]+=mar[i][i];
		k++;
	}
	if(tx+ty==n+1){
		for(int i=1; i<=n; ++i)
			zero[k]+=mar[i][n+1-i];
		k++;
	}
	ll d = tmp-zero[0];
	if(d<=0){
		printf("-1\n");
		return 0;
	}
	for(int i=1; i<k; ++i){
		if(d!=tmp-zero[i])	flag = 0;
	}	
	if(!flag)	printf("-1\n");
	else	printf("%I64d\n", d);
	return 0;
}

正解的做法应该是在0的位置上先填上一个数在判断矩阵是否合法、这样代码量就少很多、

还有我阿,特别粗心,首先没注意一定正整数,另外我在判断行和列的时候没有判断对角线。。。


C. Coloring Trees

题意:有n颗树,每一颗数上都有一个数值,0代表这个数还没涂上颜色,tree[i]>0代表这个数的颜色为tree[i],给出n,m,k,m代表有多少中颜色可以用编号是1到m,k代表魅力值为k,美丽值是这样定义的连续的一段相同的颜色的树美丽值为1,然后叠加就成了n课树的美丽值,最后给出n棵树涂上1到m中每种颜色的energy,求最小的eremgy

思路:n棵树n种美丽值m种颜色,定义状态dp[i][j][k] 前i棵树美丽值为j且第i棵树颜色为k的时候的最小energy

那么当第i棵树的颜色和第i-1棵树的颜色不同时 dp[i][j+1][k] = min(dp[i][j+1][k], dp[i-1][j][l]+color[i][k])

颜色相同时  dp[i][j][k] = min(dp[i][j][k], dp[i-1][j][l])

这里只是简单的分析,还要讨论第i课树是否为有颜色然后再去转移状态

有颜色的数不需要再计算energy,只需要求出没有颜色的树涂上颜色的最小energy

#include<algorithm>
#include<cmath>
#include<stdio.h>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
typedef __int64 ll;
const int qq = 100+5;
const ll MAX = 1e16 + 10;
int tree[qq];
int color[qq][qq];
ll dp[qq][qq][qq];	//dp[i][j][k]´ú±íÇ°i¿ÃÊ÷ÃÀÀöֵΪjÇÒµÚi¿ÃÊ÷ÑÕɫΪkµÄʱºòµÄ×îСenergy¡¢ 
int main(){
	int n,m,k;scanf("%d%d%d",&n,&m,&k);
	for(int i=1; i<=n; ++i)	scanf("%d",&tree[i]);
	for(int i=1; i<=n; ++i)
		for(int j=1; j<=m; ++j)
			scanf("%d",&color[i][j]);
	for(int i=1; i<=n; ++i)
		for(int j=1; j<=n; ++j)
			for(int l=1; l<=m; ++l)
				dp[i][j][l] = MAX;
	if(tree[1])	dp[1][1][tree[1]] = 0;
	else	for(int i=1; i<=m; ++i)	dp[1][1][i]=color[1][i];
	for(int i=2; i<=n; ++i)
		if(!tree[i]){
			for(int j=1; j<i; ++j)
				for(int l=1; l<=m; ++l)
					for(int c=1; c<=m; ++c)
						if(l!=c)	dp[i][j+1][c]=min(dp[i][j+1][c], dp[i-1][j][l]+color[i][c]);
						else	dp[i][j][c]=min(dp[i][j][c], dp[i-1][j][l]+color[i][c]);
		}
		else{
			for(int j=1; j<i; ++j)
				for(int l=1; l<=m; ++l)
					if(l!=tree[i])	dp[i][j+1][tree[i]]=min(dp[i][j+1][tree[i]], dp[i-1][j][l]);
					else	dp[i][j][tree[i]]=min(dp[i][j][tree[i]], dp[i-1][j][l]);
		}
	ll ans = MAX;
	for(int i=1; i<=m; ++i)
		ans=min(ans, dp[n][k][i]);
	if(ans==MAX)	ans = -1;
	printf("%I64d\n",ans);
	return 0;
}



版权声明:吸猫大法、

相关文章推荐

Codeforces Round #369 (Div. 2) -- C. Coloring Trees (三维DP)

大体题意: 给你n 个树,你要给这些树染色,  标号是0 表示这棵树还没有染色,标号不是0 表示这棵树已经染色 不需要再染,这片树的美丽程度是  连续相同颜色的数目! 告诉你指定美丽程度K,和  最多...

[Codeforces Round #369 (Div. 2)D. Directed Roads]Tarjan强连通分量+组合计数

[Codeforces Round #369 (Div. 2)D. Directed Roads]Tarjan强连通分量题目链接:[Codeforces Round #369 (Div. 2)D. D...

Codeforces Round #369 (Div. 2) 手速练习赛

一不小心打开cf发现有一场div2在20:00,感觉非常资瓷,作为一个unrated狗感觉是个很好的涨分机会,然后就去注册了。        打比赛前发现注册8000+,害怕。。。        比赛...

[Codeforces Round #369 (Div. 2) C. Coloring Trees] DP

[Codeforces Round #369 (Div. 2) C. Coloring Trees] DP题目链接:[Codeforces Round #369 (Div. 2) C. Colorin...

codeforces Round #369 (Div. 2) C. Coloring Trees (三维DP)

 C. Coloring Trees time limit per test 2 seconds memory limit per test ...

Codeforces Round #369 (Div. 2) D. Directed Roads

题目链接题意:给你一个n个点,n条有向边的图,你可以使任意条边反向,但是每条边只能反向一次,请求出使图不存在环的所有方案数量仔细思考我们发现,对于一个点数为x的环,除去全部不反向和全部反向两种情况,其...
  • naipp
  • naipp
  • 2016年08月30日 23:28
  • 109

codeforces Round#369 div2-E ZS and The Birthday Paradox

题意: 一年中有2^n天,问有k个人至少有两个人生日在同一天的概率,用分数表示。其中n,k 题解:1e6+3为素数。直接求不好求,我们可以总数-不成立的数。不成立的即为k个人中没有一个人的生日在同一...

Codeforces Round #369 (Div. 2) A. Bus to Udayland【模拟】

题意:公共汽车座位,每一排有四个座位,中间的 '|' 代表过道,'O' 代表空位置,'X' 代表有人座,问你能否找到两个连在一起的座位(中间有过道不算),如果可以的话吧相应的符号变为 '+'。 简单模...

Codeforces Round #369 (Div. 2) B. Chris and Magic Square

B. Chris and Magic Square time limit per test 2 seconds memory limit per test 256 megaby...

Codeforces Round #369 (Div. 2) D. Directed Roads (dfs+组合数学 图论)

传送门:D. Directed Roads 描述: D. Directed Roads time limit per test 2 seconds memory li...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Codeforces Round #369 (Div. 2)
举报原因:
原因补充:

(最多只允许输入30个字)