NCST 2018-2019秋季学期17级个人排位赛(三)
A : 养生茶的制作
Time Limit:1.000 Sec Memory Limit:128 MiB
Description
F学长是一个非常懂得生活的人,平时喜欢制作一些养生的物品,这天F学长正在根据自己的机密配方制作养生茶,
其中有两种配料|
和&
有着严格的添加顺序,必须先添加完|
后才能再添加&
,只有这样两种材料才会融合,其他任何方式的添加都不能使材料融合(也可以完全不加这两种材料)。
如果两种材料不能融合那么就是一种错误的制作方法,现在给你一些制作方法,请你判断这些方法是正确的还是错误的。
Input
一个数\(n\)表示有\(n\)组数据
每组数据由一个字符串组成,长度小于\(50\)
Output
Yes
或No
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\)个由T
,I
和O
组成的字符串,长度小于\(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;
}