NCST 2018-2019秋季学期17级个人排位赛(三)

参考题解Reference Solution



A : 养生茶的制作

Time Limit:1.000 Sec Memory Limit:128 MiB

Description

F学长是一个非常懂得生活的人,平时喜欢制作一些养生的物品,这天F学长正在根据自己的机密配方制作养生茶,

其中有两种配料|&有着严格的添加顺序,必须先添加完|后才能再添加&,只有这样两种材料才会融合,其他任何方式的添加都不能使材料融合(也可以完全不加这两种材料)。

如果两种材料不能融合那么就是一种错误的制作方法,现在给你一些制作方法,请你判断这些方法是正确的还是错误的。

Input

一个数\(n\)表示有\(n\)组数据

每组数据由一个字符串组成,长度小于\(50\)

Output

YesNo



Sample Input

4
&FXZWD!!!|
|FXZNB!!!&
||NCSTOJ&
|&|&|&|&|&



Sample Output

No
Yes
No
Yes



PZ's Solution

1.一道栈的模板题;

2.扫描当前字符串,当扫描到|时,将其入栈;当扫描到&,将一个|出栈;

3.如果需要出栈时,栈中没有元素,非法;如果扫描完毕后,栈中还有元素,非法;

  • TAG:栈



PZ.cpp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
int n;
string str;
int main(){
	scanf("%d",&n);
	while(n--){
		cin>>str;
		stack<char>s;
		bool f=0;
		for(int i=0;i<str.size();++i){
			if(str[i]=='|')
				s.push(str[i]);
			if(str[i]=='&'){
				if(s.empty()) f=1;
				else s.pop();
			}
		}
		if(f||!s.empty()) puts("No");
		else puts("Yes");
	}
	return 0;
}






B : TIO的得分

Time Limit:1.000 Sec Memory Limit:128 MiB

Description

给出\(n\)个由TIO组成的字符串,长度小于\(50\),统计所有字符的得分和,每个O的得分为目前连续出现的O的个数,每个I得两分而且不累计,T的得分为\(0\)分。

例如:OTITOOOTITOIIT的得分为\(1+0+2+0+1+2+3+0+2+0+1+2+2+0=16\)

Input

一个数\(n\),表示有\(n\)组数据

接下来\(n\)行,每行一个字符串

Output

\(n\)行,每行为字符串的得分



Sample Input

1
OTITOOOTITOIIT



Sample Output

16



PZ's Solution

1.直接扫描字符串即可;

2.注意每个O的得分为目前连续出现的O的个数即可;

  • TAG:字符串



PZ.cpp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,Osum,ans;
string s;
int main(){
	scanf("%d",&n);
	while(n--){
		cin>>s;
		Osum=ans=0;
		for(int i=0;i<s.size();++i){
			if(s[i]=='O'){
				++Osum;
				ans+=Osum;
			}else{
				Osum=0;
				if(s[i]=='I') ans+=2;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}






C : 除法

Time Limit:1.000 Sec Memory Limit:128 MiB

Description

输入正整数\(n\),从小到大输出所有形如\(abcde / fghij = n\)的表达式,其中\(a\sim j\)恰好为数字\(0 \sim 9\)的一个排列(可以有前导\(0\)),\(2 \leqslant n \leqslant 79\)

Input

\(n\)

\(n\)\(0\)时表示输入结束

Output

每种可能的情况,顺序为\(abcde\)从小到大输出

形式如: \(xxxxx/xxxxx=n\)

如果没有满足的等式,输出There are no solutions



Sample Input

61
62
0



Sample Output

There are no solutions
79546/01283=62
94736/01528=62



Solution

1.使\(fghij\)\(1234\)开始循环,这样可以直接得到\(abcde=fghij \times n\)

2.每次得到\(fghij\)\(abcde\)后,判断其是否为一个排列即可;

  • TAG:模拟



std.cpp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,fghij,abcde;
bool check(int x,int y){
	bool vis[10]={0};
	for(int i=1;i<=5;++i){
		if(vis[x%10]||vis[y%10]||x%10==y%10) return 0;
		vis[x%10]=1;
		vis[y%10]=1;
		x/=10;
		y/=10;
	}
	return 1;
}
int main(){
	while(scanf("%d",&n)&&n!=0){
		bool f=0;
		for(fghij=1234;;fghij++){
			abcde=fghij*n;
			if(abcde>98765) break;
			if(check(abcde,fghij)){
				f=1;
				printf("%05d/%05d=%d\n",abcde,fghij,n);
			}
		}
		if(!f) puts("There are no solutions");
	}
	return 0;
}






D : 素数环

Time Limit:1.000 Sec Memory Limit:128 MiB

Description

输入正整数\(n\),把整数\(1,2,. . . ,n\)组成一个环(每组第一个数都是1),使得相邻的两个整数之和均为素数。一个环恰好输出一次。

多组数据,读入EOF结束

Input

\(n(n \leqslant 16)\)

Output

所有情况

第i组数据输出时加上一行Case i:

每一行最后一个数后没有空格

相邻两组数据之间加上空行

详见样例



Sample Input

6
8



Sample Output

Case 1:
1 4 3 2 5 6
1 6 5 2 3 4

Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2



Pz's solution

本题出处为HDU 1016 Prime Ring Problem

1.首先,考虑到最大能拼成的数为\(18+19=37\),可以先预处理出\(1 \sim 40\)之间的质数;

2.在保证前一项与当前搜索项相加为质数的情况下进行搜索;

3.当搜索到最后一个数时,特判一下\(1\)与之相加是否为质数即可;

  • TAG:搜索;质数



PZ.cpp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 40
int n,T,ans[N],p[N];
bool vis[N],used[N];
void init(){
	vis[0]=vis[1]=1;
	for(int i=2;i<N;++i){
		if(!vis[i]) p[++p[0]]=i;
		for(int j=1;j<=p[0]&&p[j]*i<N;++j){
			vis[p[j]*i]=1;
			if(i%p[j]==0) break;
		}
	}
}
void dfs(int res){
	if(res==n){
		if(!vis[1+ans[n]])
			for(int i=1;i<=n;++i){
				printf("%d%c",ans[i],(i==n ? '\n' : ' '));
			}
		return;
	}
	for(int i=2;i<=n;++i)
		if(!used[i])
			if(!vis[ans[res]+i]){
				ans[res+1]=i;
				used[i]=1;
				dfs(res+1);
				used[i]=0;
			}
}
int main(){
	init();
	while(scanf("%d",&n)!=EOF){
		++T;
		memset(used,0,sizeof(used));
		memset(ans,0,sizeof(ans));
		ans[1]=1;
		printf("Case %d:\n",T);
		dfs(1);
		putchar('\n');//注意样例输出格式 
	}
	return 0;
}






E : F学长的养生茶!!!

Time Limit:1.000 Sec Memory Limit:128 MiB

Description

F学长刚刚制作好的养生茶被坏同学偷偷的放在了迷宫里的一个地方。

迷宫用\(N*M\)的矩阵表示\((N,M\leqslant 100)\)矩阵中的每项可以代表道路(@),墙壁(#)和高数题(x)年轻的F学长(r)决定去寻找他的养生茶(a),由于坏同学在路上放了很多高数题,F学长必须解决高数题后才能继续前进,每移动一个位置需要花费\(1\)个单位时间,做出一道高数题也需要\(1\)个单位时间,同时F学长非常聪明,能做出所有的高数题。

给定迷宫,养生茶,F学长和高数题的位置,计算找到养生茶所需要的最短时间。

Input

第一行\(t\),表示有\(t\)组数据

每组数据有\(n,m\),代表迷宫行和列

迷宫中@代表道路,a代表养生茶,r代表F学长,x代表高数题,#代表墙壁

Output

如果F学长能找到他的养生茶,输出行动所需最短时间,否则输出Impossible



Sample Input

1
7 8
#@#####@
#@a#@@r@
#@@#x@@@
@@#@@#@#
#@@@##@@
@#@@@@@@
@@@@@@@@



Sample Output

13



PZ's Solution

1.数据很小,可以直接考虑BFS;

2.不过这里需要运用最短路思想,其实可以看做SPFA来做;

  • TAG:BFS广度优先搜索;最短路



PZ.cpp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int T,n,m,ans[105][105],sx,sy,ex,ey,nx,ny,diss;
char mp[105][105];
int fx[]={0,0,1,-1};
int fy[]={1,-1,0,0};
queue<int>qx,qy;
bool check(int x,int y){ return 1<=x&&x<=n&&1<=y&&y<=m; }
void bfs(){
	qx.push(sx); qy.push(sy); ans[sx][sy]=0;
	while(!qx.empty()){
		int x=qx.front(); qx.pop();
		int y=qy.front(); qy.pop();
		for(int i=0;i<4;++i){
			nx=x+fx[i]; ny=y+fy[i];
			if(!check(nx,ny)||mp[nx][ny]=='#') continue;
			if(mp[nx][ny]=='x') diss=2; else diss=1;
			if(ans[nx][ny]>ans[x][y]+diss){
				ans[nx][ny]=ans[x][y]+diss;
				qx.push(nx); qy.push(ny);
			}
		}
	}
}
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d %d",&n,&m);
		memset(ans,0x3f,sizeof(ans));
		for(int i=1;i<=n;++i)
			for(int j=1;j<=m;++j){
				cin>>mp[i][j];
				if(mp[i][j]=='r') sx=i,sy=j;
				if(mp[i][j]=='a') ex=i,ey=j;
			}
		bfs();
		if(ans[ex][ey]!=0x3f3f3f3f) printf("%d\n",ans[ex][ey]);
		else puts("Impossible");
	}
	return 0;
}
posted @ 2021-02-10 17:35  PotremZ  阅读(76)  评论(0编辑  收藏  举报