栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

CSP 2015-12

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CSP 2015-12

1.数位和

#include
using namespace std;

int main(){
	char c;
	int ans=0;
	while(cin.get(c)){
		if(c=='n') break;
		ans+=c-'0';
	}	
	cout< 

2.消除游戏

#include
using namespace std;
//思路:对于每一个棋子,判断其是否可以被消掉,将要被消除的点进行标记,待遍历完毕后记为0
// 如何判断? 找到该棋子左右上下的边界即可,判断边界大小是否大于等于3 
#define N 40
struct node{
	int c,v;
}a[N][N];
int n,m;

bool could_del(int x,int y){
	int u,d,r,l;
	for(u=x;u>=0&&a[u][y].c==a[x][y].c;u--);
	for(d=x;d=0&&a[x][l].c==a[x][y].c;l--);
	return d-u>=4||r-l>=4;	
}

int main(){
	cin>>n>>m;
	for(int i=0;i>a[i][j].c,a[i][j].v=0;
	
	for(int i=0;i 

3.画图
直接模拟就可以:但是这个题有两个坑

  • 数学坐标系写代码太麻烦了
    -如果之前的字符是’+‘的话,那么经过画线过后不应该被覆盖为’-‘或者’|’,不然只能拿90分
#include
#include
using namespace std;
#define N 110
char a[N][N];
int n,m,q;

void _line(int x1,int y1,int x2,int y2){
	if(x1==x2){
		int ymax=max(y1,y2);
		int ymin=min(y1,y2);
		for(int i=ymin;i<=ymax;i++){
			if(a[x1][i]=='-'||a[x1][i]=='+') a[x1][i]='+';
			else a[x1][i]='|';
		}
	}else{
		int xmax=max(x1,x2);
		int xmin=min(x1,x2);
		for(int i=xmin;i<=xmax;i++){
			if(a[i][y1]=='|'||a[i][y1]=='+') a[i][y1]='+';
			else a[i][y1]='-';
		}
	}
}

int dir[][2]={0,1,0,-1,1,0,-1,0};

void _fill(int x,int y,char c){
	if(a[x][y]==c) return ;
	a[x][y]=c;
	for(int i=0;i<4;i++){
		int nx=x+dir[i][0];
		int ny=y+dir[i][1];
		if(nx<0||nx>=m||ny<0||ny>=n) continue;
		if(a[nx][ny]=='|'||a[nx][ny]=='-'||a[nx][ny]=='+') continue;
		_fill(nx,ny,c);
	}
}

int main(){
		cin>>m>>n>>q;
		_fill(0,0,'.');
		while(q--){
			int o;
			cin>>o;
			if(o){
				int x,y;
				char c;
				cin>>x>>y>>c;
				_fill(x,y,c);
			}else{
				int x1,y1,x2,y2;
				cin>>x1>>y1>>x2>>y2;
				_line(x1,y1,x2,y2);
			}
		}

		for(int j=n-1;j>=0;j--){
			for(int i=0;i 

4.送货:
自己的代码:

#include
#include
#include
#include
using namespace std;
#define N 10010
//统计奇点个数,若1不是奇点,则无解,若奇点个数不为2也无解
//dfs求解即可 
set G[N];
int n,m;
vector res;
void dfs(int k){ //当前的位置在k
	if(!G[k].size()) return ; 
	int nxt=*G[k].begin();
	res.push_back(nxt);
	G[k].erase(nxt);
	G[nxt].erase(k);
	dfs(nxt);
}
int main(){
	cin>>n>>m;
	int k=m;
	while(m--){
		int a,b;
		cin>>a>>b;
		G[a].insert(b);
		G[b].insert(a);
	}
		
	if(G[1].size()%2==0) {
		cout<<"-1";
		return 0;
	}
	
	int cnt=0;
	for(int i=1;i<=n;i++)
	cnt+=(G[i].size()%2);
	
	if(cnt!=2&&cnt!=0){ //若没有奇点,则回路为从A出发,从A结束 
		cout<<"-1";
		return 0;
	}
	
	dfs(1);

	if(res.size()!=k) {
		cout<<"-1";
		return 0;
	}
	 
	cout<<1<<" ";
	for(int i=0;i 

错的,只有10分,分析为什么错了:

  • 在判断奇点个数时候出错了:
    正确的判断代码应该是:
	if(cnt!=2&&cnt!=0||(cnt==2&&G[1].size()%2!=1)){  
		cout<<"-1";
		return 0;
	}
  • 是因为没有用并查集判断连通性吗?
    不是,如果图是联通的,那么进行dfs后得到的vector大小一定和m相同

  • 正解,dfs函数出错,在遍历时候每次都只取该点的一条边,若该点是奇点就出错了
    正确的dfs代码如下: (至于为什么要回溯再记录,我也不清楚)

void dfs(int k){ //当前的位置在k
	while(G[k].size()){
		int t=*G[k].begin();
		G[k].erase(t);
		G[t].erase(k);
		dfs(t);
	}
	res.push_back(k);
}

y总完整代码如下:

#include
#include
#include
#include
using namespace std;
#define N 10010
//统计奇点个数,若1不是奇点,则无解,若奇点个数不为2也无解
//dfs求解即可 
set G[N];
int n,m;
vector res;
void dfs(int k){ //当前的位置在k
	while(G[k].size()){
		int t=*G[k].begin();
		G[k].erase(t);
		G[t].erase(k);
		dfs(t);
	}
	res.push_back(k);
}
int main(){
	cin>>n>>m;
	int k=m;
	while(m--){
		int a,b;
		cin>>a>>b;
		G[a].insert(b);
		G[b].insert(a);
	}
	
	int cnt=0;
	for(int i=1;i<=n;i++)
	cnt+=(G[i].size()%2);
	
	if(cnt!=2&&cnt!=0||(cnt==2&&G[1].size()%2!=1)){  
		cout<<"-1";
		return 0;
	}
	
	dfs(1);

	if(res.size()!=k+1) {
		cout<<"-1";
		return 0;
	}
	 //记得要倒着输出,因为答案也是倒着记录的
	for(int i=res.size()-1;i>=0;i--)
	cout< 

5.第五题不会

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/330010.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号