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 #406 (Div. 2):C. Berzerk(记忆化搜索解决博弈问题)

C. Berzerk time limit per test 4 seconds memory limit per test 256 megabytes input standard in...
  • Jaihk662
  • Jaihk662
  • 2017年03月24日 15:23
  • 810

【Codeforces Round 375 (Div 2) E】【欧拉回路Fleury算法 或网络流】One-Way Reform 每条边定向使得最多的点满足入度=出度

E. One-Way Reform time limit per test 2 seconds memory limit per test 256 megabytes ...
  • snowy_smile
  • snowy_smile
  • 2016年10月04日 10:20
  • 739

数学推公式——较难——Codeforces Round #187 (Div. 2)

题目链接: http://codeforces.com/contest/315/problem/C C. Sereja and Contest time limi...
  • CS_liuqing
  • CS_liuqing
  • 2013年06月16日 15:34
  • 2002

Codeforces Round #244 (Div. 2)(强连通分量,后缀数组)

A. Police Recruits #include #include #include #include using namespace std; int n; int main() { ...
  • u010660276
  • u010660276
  • 2014年05月23日 20:08
  • 424

Codeforces Round #248 (Div. 2) B题 【数据结构:树状数组】

题目链接:http://codeforces.com/contest/433/problem/B 题目大意:给n(1 ≤ n ≤ 105)个数据(1 ≤ vi ≤ 109),其中有m(1 ≤ m ≤...
  • u013912596
  • u013912596
  • 2014年05月24日 18:18
  • 709

Codeforces Round #312 (Div. 2) (第三题是位运算,好题)

比赛:点击打开链接 558A - Lala Land and Apple Trees 分析:从0坐标分开,负半轴一个数组,正半轴一个数组,来记录果树的左边和数量,可以用结构体数组来存储数据,其...
  • loveyou11111111
  • loveyou11111111
  • 2015年08月31日 16:30
  • 160

【打CF,学算法——三星级】CodeForces 689C Mike and Chocolate Thieves (二分)

题目链接:CF 689C 题面: C. Mike and Chocolate Thieves time limit per test 2 seconds memory limit ...
  • David_Jett
  • David_Jett
  • 2016年07月08日 10:55
  • 795

【专题】线段树

单点更新 最最基础的线段树,只更新叶子节点,然后把信息用PushUP(int r)这个函数更新上来。 hdu1166 敌兵布阵 线段树 hdu 1166 敌兵布阵 单点更新区间求和 hdu1754 ...
  • cyendra
  • cyendra
  • 2013年05月12日 17:33
  • 740

Codeforces Round #303 (Div. 2) E 最短路迪杰斯特拉(小根堆实现)

链接:戳这里 E. Paths and Trees time limit per test3 seconds memory limit per test256 megabytes...
  • libin66
  • libin66
  • 2016年07月22日 17:29
  • 289

Codeforces Round #383 (Div. 2) C(递归找环求最小公倍数)

题目链接 题目大意:表示意思有点绕,什么owww的,通俗的来讲就是找环,问的是满足x走到y的步数可以让y走到x。 分析 那么如果x走到x是一个偶数n,说明可以用n/2走到y且y不等于x 然后再...
  • HHH_go_
  • HHH_go_
  • 2016年12月07日 14:01
  • 299
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Codeforces Round #369 (Div. 2)
举报原因:
原因补充:

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