A - How Many Tables
题目大意:给所有到场参加party的人安排最少需要的桌子,要求认识的要坐在一起。
输入:样例个数T,接下来第一行给出总共的人数N和好友对数M,其后每行给出一对好友。
输出:最少需要的桌子数。
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int pre[1005];
int t,n,m;
void init() {
for(int i=1; i<=n; i++)
pre[i]=i;
}
int Find(int x){
while(x!=pre[x]){
pre[x]=pre[pre[x]];
x=pre[x];
}
return x;
}
void Merge(int x,int y){
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
pre[fx]=fy;
}
int main() {
int x,y;
cin>>t;
for(int i=0; i<t; i++) {
scanf("%d%d",&n,&m);
init();
for(int j=1; j<=m; j++) {
scanf("%d%d",&x,&y);
Merge(x,y);
}
int cnt=0;
for(int i=1; i<=n; i++) {
if(pre[i]==i) cnt++;
}
cout<<cnt<<endl;
}
return 0;
}
B - Wireless Network
题目大意:有一些电脑,编号为1到N,现在这些电脑坏了,无法相互连通需要维修,输入首先输入电脑总数N和d(d表示两台已维修好的电脑若它们之间的距离小于等于d,则两台电脑可以互通)。接下来输入N行,每行输入a,b两个数,N行中的第i行表示编号为i的电脑的坐标(用来求两台电脑的距离),在接下来的输入各种操作,O a表示编号为a的电脑被维修好了,S a b则表示询问编号为a和b的电脑能不能互通,若能则输出SUCCESS,若不能则输出FAIL。
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
int pre[1005];
bool good[1005];
int n,d;
struct node {
int x,y;
} pt[1005];
void init() {
memset(good,false,sizeof good);
for(int i=1; i<=n; i++)
pre[i]=i;
}
bool judge(node a,node b) {
return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))<=d*d;
}
int Find(int x) {
while(x!=pre[x]) {
pre[x]=pre[pre[x]];
x=pre[x];
}
return x;
}
bool Same(int x,int y){
return Find(x)==Find(y);
}
void Merge(int x,int y) {
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
pre[fx]=fy;
}
int main() {
int x,y;
string s;
cin>>n>>d;
init();
for(int i=1; i<=n; i++)
scanf("%d%d",&pt[i].x,&pt[i].y);
while(cin>>s) {
if(s[0]=='O') {
scanf("%d",&x);
good[x]=true; //该电脑已修好
for(int i=1; i<=n; i++) {
if(good[i]==true){
if(judge(pt[i],pt[x]))
Merge(i,x);
}
}
} else if(s[0]=='S') {
scanf("%d%d",&x,&y);
if(Find(x)==Find(y)) //一不小心方括号
cout<<"SUCCESS\n";
else
cout<<"FAIL\n";
}
}
return 0;
}
C - The Suspects
题目大意:有多组学生,在同一个组的学生经常会接触,也会有新的同学的加入。但是SARS是很容易传染的,只要该组有一位同学感染SARS,那么该组的所有同学都被认为得了SARS。现在的任务是计算出有多少位学生感染SARS了。假定编号为0的同学是得了SARS的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int pre[30005]; //记录编号为i的人的祖先,数组一定要随题变更
int num[30005]; //记录编号为i的这个团体有多少人
int a[30005];
int find(int x){
while(x!=pre[x]){
x=pre[x]; //这样处理效率更高
pre[x]=pre[pre[x]];
}
return x;
}
void Merge(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy){
pre[fx]=fy; //x的祖先变更为y,所以y的num扩充+
num[fy]+=num[fx];
}
return;
}
int main(){
int n,m,x,y,cnt;
while(scanf("%d%d",&n,&m)&&(n||m)){ //注意这种写法——n||m
for(int i=0;i<n;i++){
pre[i]=i;
num[i]=1; //初始化的num只有它本身即——1
}
for(int i=1;i<=m;i++){
scanf("%d",&cnt);
for(int i=1;i<=cnt;i++){
scanf("%d",&a[i]);
} //先读入后合并
for(int i=1;i<cnt;i++){
Merge(a[i],a[i+1]);
}
}
int ans=find(0); //ans记录编号为0的祖先
printf("%d\n",num[ans]);
}
return 0;
}
D - 超级楼梯
有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?
Input
输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M(1<=M<=40),表示楼梯的级数。
Output
对于每个测试实例,请输出不同走法的数量
Sample Input
2 2 3Sample Output
1 2
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
int fun(int n){
if(n==1||n==2) return 1; //!!!
else return fun(n-1)+fun(n-2);
}
int main() {
int n,m;
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&m);
printf("%d\n",fun(m));
}
return 0;
}
E - IP Address
Suppose you are reading byte streams from any device, representing IP addresses. Your task is to convert a 32 characters long sequence of '1s' and '0s' (bits) to a dotted decimal format. A dotted decimal format for an IP address is form by grouping 8 bits at a time and converting the binary representation to decimal representation. Any 8 bits is a valid part of an IP address. To convert binary numbers to decimal numbers remember that both are positional numerical systems, where the first 8 positions of the binary systems are:
27 26 25 24 23 22 21 20 128 64 32 16 8 4 2 1 Input
The input will have a number N (1 <= N <= 9) in its first line representing the number of streams to convert. N lines will follow.
Output
The output must have N lines with a doted decimal IP address. A dotted decimal IP address is formed by grouping 8 bit at the time and converting the binary representation to decimal representation.
Sample Input
4
00000000000000000000000000000000
00000011100000001111111111111111
11001011100001001110010110000000
01010000000100000000000000000001
Sample Output
0.0.0.0
3.128.255.255
203.132.229.128
80.16.0.1
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
void Solve(string s,int flag) {
int sum=0;
reverse(s.begin(),s.end()); //从后往前遍历,i不与指数对应,切记!
for(int i=0;s[i];i++)
if(s[i]=='1') sum+=pow(2,i);
cout<<sum;
if(flag!=4) cout<<'.';
else cout<<endl;
}
int main() {
int n;
string s,s1,s2,s3,s4;
cin>>n;
while(n--) {
cin>>s;
s1=s.substr(0,8); //从下标0开始截取长度为8
s2=s.substr(8,8);
s3=s.substr(16,8);
s4=s.substr(24); //从下标24开始至结尾
Solve(s1,1);
Solve(s2,2);
Solve(s3,3);
Solve(s4,4);
}
return 0;
}
F - Nine Interlinks
"What are you doing now?"
"Playing Nine Interlinks!"
"What is that?"
"Oh it is an ancient game played over China. The task is to get the nine rings off the stick according to some rules. Now, I have got them off, would you like to have a try to get them on?"
Input
The first line of the input contains an integer T (T <= 30), indicating the number of cases.
Each case consists of a simple integer n (1 < n < 30), which is the number of the total rings you need to get on the stick.
At the beginning, all rings are off the stick.
In each step, you can only get one ring on or off by the following rules:
1. You can get the first ring on or off freely at each step.
2. If the ith ring is on the stick, and the 1st, 2nd... (i-1)st rings are off the stick, you can get the (i+1)st ring on or off freely at each step.
Output
For each case, print in a single line the minimum number of steps you need to get n rings on the stick.
Sample Input
2 2 3
Sample Output
2 5
Hint
The first sample: 1 on, 2 on.
The second sample: 1 on, 2 on, 1 off, 3 on, 1 on.思路:这道题一定要自己画一下才明白,如果自己没有头绪,就根据题意和题目样例及解析手动分析,然后发现规律:每一个状态i都要经历——将i-2开,i-1开,i-2关,i开 ; 特别注意无论是否开还是关第n个都要满足1~n-2关,n-1开!
在此谢谢zg耐心讲解!
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
int a[35];
void init(){
a[0]=0;
a[1]=1;
a[2]=2;
for(int i=3;i<35;i++)
a[i]=a[i-1]+a[i-2]*2+1;
}
int main() {
int t,n;
init();
cin>>t;
while(t--){
cin>>n;
cout<<a[n]<<endl;
}
return 0;
}
G - 简单计算器
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 2 4 + 2 * 5 - 7 / 11 0Sample Output
3.00 13.36
// 4 + 2 * 5 - 7 / 11
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
stack<double> stk;
int main() {
char ch;
double n,tmp;
while(~scanf("%lf%c",&n,&ch)) { //接收空格或回车
if(ch=='\n'&&n==0) break;
stk.push(n);
ch=getchar();
while(scanf("%lf",&n)) {
if(ch=='*') {
tmp=stk.top()*n;
stk.pop();
stk.push(tmp);
} else if(ch=='/') {
tmp=stk.top()/n;
stk.pop();
stk.push(tmp);
} else if(ch=='+')
stk.push(n);
else if(ch=='-')
stk.push(-n);
if(getchar()=='\n') //本行输入完毕或空格
break;
ch=getchar(); //下一字符
}
double sum=0;
while(!stk.empty()) {
sum+=stk.top();
stk.pop();
}
printf("%.2f\n",sum);
}
return 0;
}
H - 愚人节的礼物
四月一日快到了,Vayko想了个愚人的好办法——送礼物。嘿嘿,不要想的太好,这礼物可没那么简单,Vayko为了愚人,准备了一堆盒子,其中有一个盒子里面装了礼物。盒子里面可以再放零个或者多个盒子。假设放礼物的盒子里不再放其他
盒子。
用()表示一个盒子,B表示礼物,Vayko想让你帮她算出愚人指数,即最少需要拆多少个盒子才能拿到礼物。Input
本题目包含多组测试,请处理到文件结束。
每组测试包含一个长度不大于1000,只包含'(',')'和'B'三种字符的字符串,代表Vayko设计的礼物透视图。
你可以假设,每个透视图画的都是合法的。Output
对于每组测试,请在一行里面输出愚人指数。
Sample Input
((((B)()))()) (B)Sample Output
4 1
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>
#include<stack>
using namespace std;
stack<char> st;
int main() {
string s;
while(getline(cin,s)){
int ans=0;
for(int i=0;i<s.size();i++){
if(s[i]=='B') break;
else if(s[i]=='(') ans++;
else if(s[i]==')') ans--;
}
cout<<ans<<endl;
}
return 0;
}
I - Train Problem I
As the new term comes, the Ignatius Train Station is very busy nowadays. A lot of student want to get back to school by train(because the trains in the Ignatius Train Station is the fastest all over the world ^v^). But here comes a problem, there is only one railway where all the trains stop. So all the trains come in from one side and get out from the other side. For this problem, if train A gets into the railway first, and then train B gets into the railway before train A leaves, train A can't leave until train B leaves. The pictures below figure out the problem. Now the problem for you is, there are at most 9 trains in the station, all the trains has an ID(numbered from 1 to n), the trains get into the railway in an order O1, your task is to determine whether the trains can get out in an order O2.
Input
The input contains several test cases. Each test case consists of an integer, the number of trains, and two strings, the order of the trains come in:O1, and the order of the trains leave:O2. The input is terminated by the end of file. More details in the Sample Input.
Output
The output contains a string "No." if you can't exchange O2 to O1, or you should output a line contains "Yes.", and then output your way in exchanging the order(you should output "in" for a train getting into the railway, and "out" for a train getting out of the railway). Print a line contains "FINISH" after each test case. More details in the Sample Output.
Sample Input
3 123 321 3 123 312Sample Output
Yes. in in in out out out FINISH No. FINISH For the first Sample Input, we let train 1 get in, then train 2 and train 3. So now train 3 is at the top of the railway, so train 3 can leave first, then train 2 and train 1. In the second Sample input, we should let train 3 leave first, so we have to let train 1 get in, then train 2 and train 3. Now we can let train 3 leave. But after that we can't let train 1 leave before train 2, because train 2 is at the top of the railway at the moment. So we output "No.".题意:给出一个n,有两个序列,每个序列里有n个元素,问能不能利用栈把第一个序列变成第二个序列。
分析:栈的简单应用,注意每次都要把栈清空,或者把栈定义在while循环里边也行。
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
int vis[25];
int main() {
string s1,s2;
int n;
while(~scanf("%d",&n)){
stack<char> stk; //栈清空
memset(vis,-1,sizeof vis);
int cnt1=0,cnt2=0;
cin>>s1>>s2;
for(int i=0;i<n;i++){
stk.push(s1[i]);
vis[cnt1++]=1; //按s1顺序入栈
while(!stk.empty()&&stk.top()==s2[cnt2]){ //和s2比对
vis[cnt1++]=0;
stk.pop();
cnt2++;
}
}
if(cnt2!=n) cout<<"No.\nFINISH\n";
else{
cout<<"Yes.\n";
for(int i=0;i<cnt1;i++){
if(vis[i]==1) cout<<"in\n";
else if(vis[i]==0) cout<<"out\n";
}
cout<<"FINISH\n";
}
}
return 0;
}
J - Parentheses Balance
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
char f(char ch){ //一个小函数,搞定所有哦
if(ch==')') return '(';
else if(ch==']') return '[';
else return 0;
}
bool judge(string s){ //若最后栈里只剩一个0则正确
stack<char> stk;
stk.push('0');
for(int i=0;i<s.size();i++){
if(stk.top()!=f(s[i]))
stk.push(s[i]);
else
stk.pop();
}
return stk.size()==1;
}
int main() {
int n;
string s;
cin>>n;
getchar();
while(n--){
getline(cin,s);
if(s.size()==0||judge(s)) printf("Yes\n"); //还有只含一个空格的特况
else printf("No\n");
}
return 0;
}
K - 士兵队列训练问题
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。
Input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。
Output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
Sample Input
2 20 40Sample Output
1 7 19 1 19 37
#include<iostream>
#include<queue>
using namespace std;
queue<int>q;
void Solve(int n){
int cnt=1;
while(q.front()!=0){
if(cnt%n) q.push(q.front());
q.pop();
cnt++;
}
q.pop();
q.push(0); //依旧以0结尾,棒棒哒!
}
int main(){
int n,m;
cin>>n;
while(n--){
scanf("%d",&m);
for(int i=1;i<=m;i++)
q.push(i);
q.push(0);
int cnt=1;
while(q.size()>4){
if(cnt%2) Solve(2); //按题目要求执行函数呀~
else Solve(3);
cnt++;
}
int isfirst=1;
while(!q.empty()){
if(q.front()>0){
if(!isfirst) cout<<' ';
else isfirst=0;
cout<<q.front();
}
q.pop(); //即使是零也要pop掉(公共)
}
cout<<endl;
}
return 0;
}
L - ACboy needs your help again!
ACboy was kidnapped!!
he miss his mother very much and is very scare now.You can't image how dark the room he was put into is, so poor :(.
As a smart ACMer, you want to get ACboy out of the monster's labyrinth.But when you arrive at the gate of the maze, the monste say :" I have heard that you are very clever, but if can't solve my problems, you will die with ACboy."
The problems of the monster is shown on the wall:
Each problem's first line is a integer N(the number of commands), and a word "FIFO" or "FILO".(you are very happy because you know "FIFO" stands for "First In First Out", and "FILO" means "First In Last Out").
and the following N lines, each line is "IN M" or "OUT", (M represent a integer).
and the answer of a problem is a passowrd of a door, so if you want to rescue ACboy, answer the problem carefully!Input
The input contains multiple test cases.
The first line has one integer,represent the number oftest cases.
And the input of each subproblem are described above.Output
For each command "OUT", you should output a integer depend on the word is "FIFO" or "FILO", or a word "None" if you don't have any integer.
Sample Input
4 4 FIFO IN 1 IN 2 OUT OUT 4 FILO IN 1 IN 2 OUT OUT 5 FIFO IN 1 IN 2 OUT OUT OUT 5 FILO IN 1 IN 2 OUT IN 3 OUTSample Output
1 2 2 1 1 2 None 2 3
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
void FIFO(int n){ //小伙子你的代码又“精致”了哦~
string s;
int num;
queue<int> q;
while(n--){
cin>>s;
if(s[0]=='I'){
cin>>num;
q.push(num);
}
else{
if(q.empty()) cout<<"None\n";
else{
cout<<q.front()<<endl;
q.pop();
}
}
}
}
void FILO(int n){
string s;
int num;
stack<int> st;
while(n--){
cin>>s;
if(s[0]=='I'){
cin>>num;
st.push(num);
}
else{
if(st.empty()) cout<<"None\n";
else{
cout<<st.top()<<endl;
st.pop();
}
}
}
}
int main() {
int n,num;
string order;
cin>>n;
while(n--){
cin>>num>>order;
if(order[2]=='F')
FIFO(num);
else
FILO(num);
}
return 0;
}
插播——
- 2019年大年初一第一顿饭恭喜我吃到硬币得好彩头哦~不过努力加运气才会更可爱!
- (吃完大年初一团圆饭的个人小感受:)能有这么一位既幽默又有远见的长辈实在是我人生之大幸!听叔一席话,胜读十年书!
- 总之,相信自己,未来可期!小鱼加油!