目录

  • @[TOC](目录)
  • 一、Atcoder
    • 1.Average Length
    • 2.Knight
  • 二、codeforces
    • 1.Two Rival Students
    • 2.Magic Stick
  • 三、牛客网-四川大学新生赛
    • 1.丁姐喜欢LCS
    • 2.俏兔子大战傻贼鹰-Easy Version
    • 3.俏兔子大战傻贼鹰-Hard Version
    • 4.欧拉筛
    • 5.后缀自动机
    • 6.双流机场
    • 7.n=a*b*c
  • 四、PTA
    • 1.括号匹配
    • 2.堆栈操作合法性
    • 3.汉诺塔的非递归实现

一、Atcoder

1.Average Length

题意

There are N towns in a coordinate plane. Town i is located at coordinates (xi, yi). The distancebetween Town i and Town j is √(xi−xj)^2+(yi−yj) ^2.

There are N! possible paths to visit all of these towns once. Let the length of a path be the distance covered when we start at the first town in the path, visit the second, third, …, towns, and arrive at the last town (assume that we travel in a straight line from a town to another). Compute the average length of these N! paths.

2≤N≤8
−1000≤xi≤1000
−1000≤yi≤1000
(xi,yi)≠(xj,yj) (if i≠j)
(Added 21:12 JST) All values in input are integers.

输入

Input is given from Standard Input in the following format:

N
x1 y1
:
xN yN

输出

Print the average length of the paths. Your output will be judges as correct when the absolute difference from the judge’s output is at most 10^−6.

样例输入1

3
0 0
1 0
0 1

样例输出1

2.2761423749

There are six paths to visit the towns: 1 → 2 → 3, 1 → 3 → 2, 2 → 1 → 3, 2 → 3 → 1, 3 → 1 → 2, and 3 → 2 → 1.
The length of the path 1 → 2 → 3 is √(0−1)^2+(0−0) ^2+√(1−0) 2+(0−1) ^2=1+√2.
By calculating the lengths of the other paths in this way, we see that the average length of all routes is:
((1+√2)+(1+√2)+(2)+(1+√2)+(2)+(1+√2))/6=2.276142…

样例输入2

2
-879 981
-866 890

样例输出2

91.9238815543

样例输入3

8
-406 10
512 859
494 362
-955 -475
128 553
-986 -885
763 77
449 310

样例输出3

7641.9817824387

解题思路

这题看上去就知道要用DFS,但是我用DFS无从下手,我就用了数学方法,找到了他们之间的规律,但是我改代码改了好久,最后终于过了。其实就是每两个点之间的距离的次数是有一定规律的,把次数算出来,然后算一次距离,然后乘上次数就可以了。
后来我又去找了一个用DFS写的代码,学习一下。

程序代码:(My-AC)

#include<bits/stdc++.h>
using namespace std;
const int N=10;
struct node{int x,y;
}a[N];
double num[N][N];
double ans=0;
int n;
int nn[]={0,0,2,4,12,48,240,1440,10080};
int f(int n){int t=1;for(int i=1;i<=n;i++){t=t*i;}return t;
}
//int f1(int n){//  if(n==2){//      return 1;
//  }
//  return n*(n-1)/f(n-2);
//}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d %d",&a[i].x,&a[i].y);}
//  int len=f(n)*(n-1)/f1(n);for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){num[i][j]=sqrt(1.0*(a[i].x-a[j].x)*(a[i].x-a[j].x)+1.0*(a[i].y-a[j].y)*(a[i].y-a[j].y));ans+=(num[i][j]*nn[n]);}}printf("%.10f\n",ans/f(n));return 0;
}

程序代码:(DFS-AC)

#include"bits/stdc++.h"
using namespace std;
struct point{double x,y;
}p[10000];
double n;
int num=0;
double ans=0;
int a[10],flag[10];
void dfs(int now){if(now==n){num++;for(int i=0;i<n-1;i++){//cout<<"    "<<a[i];//cout<<sqrt((double)(p[a[i]].x-p[a[i]+1].x)*(p[a[i]].x-p[a[i]+1].x)+(double)(p[a[i]].y-p[a[i]+1].y)*(p[a[i]].y-p[a[i]+1].y))<<endl;ans+=(double)sqrt((double)(p[a[i]].x-p[a[i+1]].x)*(p[a[i]].x-p[a[i+1]].x)+(double)(p[a[i]].y-p[a[i+1]].y)*(p[a[i]].y-p[a[i+1]].y));}return;}for(int i=1;i<=n;i++){if(flag[i]==0){flag[i]=1;a[now]=i;dfs(now+1);flag[i]=0;}}
}
int main(){cin>>n;for(int i=1;i<=n;i++){scanf("%lf%lf",&p[i].x,&p[i].y);}dfs(0);printf("%.10f",ans/num);return 0;
}

2.Knight

题意

There is a knight - the chess piece - at the origin (0,0) of a two-dimensional grid.
When the knight is at the square (i,j), it can be moved to either (i+1,j+2) or (i+2,j+1).
In how many ways can the knight reach the square (X,Y)?

Find the number of ways modulo 10^9+7.

1≤X≤10^6
1≤Y≤10^6
All values in input are integers.

输入

Input is given from Standard Input in the following format:

X Y

输出

Print the number of ways for the knight to reach (X,Y) from (0,0), modulo 10^9+7.

样例输入1

3 3

样例输出1

2

There are two ways: (0,0)→(1,2)→(3,3) and (0,0)→(2,1)→(3,3).

样例输入2

2 2

样例输出2

0

The knight cannot reach (2,2).

样例输入3

999999 999999

样例输出3

151840682

Print the number of ways modulo 10^9+7.

解题思路

其实这道题我没有写,当时写完第三题,时间就差不多快结束了,就没写这道题了。
以下是我找的别人写的代码。

程序代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
const int p = 1e9 + 7;
int f[maxn+10];
void init(){f[0]=1;for(int i=1;i<=maxn;i++){f[i]=(long long)f[i-1]*i%p;}
}int fast(int a,int n){if(n==0)return 1;if(n%2)return (long long)a*fast(a,n-1)%p;int tmp=fast(a,n/2);return (long long)tmp*tmp%p;
}int C(int n,int m){if(n==m||m==0)return 1;return ((long long)f[n]*fast(f[m],p-2)%p)*fast(f[n-m],p-2)%p;
}int main() {int x,y;scanf("%d%d",&x,&y);int t1 = (2*y-x);   int t2 = (2*x-y);if(t1 % 3 != 0 || t2 %3 != 0 || t1 < 0 || t2 < 0){printf("0\n");}else{init();t1 = t1/3;t2 = t2/3;printf("%d\n",C(t1+t2,t1));}return 0;
}

二、codeforces

1.Two Rival Students

题意

You are the gym teacher in the school.

There are n students in the row. And there are two rivalling students among them. The first one is in position a, the second in position b. Positions are numbered from 1 to n from left to right.

Since they are rivals, you want to maximize the distance between them. If students are in positions p and s respectively, then distance between them is |p−s|.

You can do the following operation at most x times: choose two adjacent (neighbouring) students and swap them.

Calculate the maximum distance between two rivalling students after at most x swaps.

输入

The first line contains one integer t (1≤t≤100) — the number of test cases.

The only line of each test case contains four integers n, x, a and b (2≤n≤100, 0≤x≤100, 1≤a,b≤n, a≠b) — the number of students in the row, the number of swaps which you can do, and positions of first and second rivaling students respectively.

输出

For each test case print one integer — the maximum distance between two rivaling students which you can obtain.

样例输入

3
5 1 3 2
100 33 100 1
6 0 2 3

样例输出

2
99
1

In the first test case you can swap students in positions 3 and 4. And then the distance between the rivals is equal to |4−2|=2.
In the second test case you don’t have to swap students.
In the third test case you can’t swap students.

解题思路

其实不用考虑太多,就是看b-a的大小,然后分情况输出。

程序代码

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){int T;scanf("%d",&T);while(T--){int n,x,a,b;scanf("%d %d %d %d",&n,&x,&a,&b);if(a>b){swap(a,b);}if((b-a)==(n-1)){printf("%d\n",b-a);continue;}if((b-a+x)>(n-1))printf("%d\n",n-1);elseprintf("%d\n",b-a+x);}return 0;
}

2.Magic Stick

题意

Recently Petya walked in the forest and found a magic stick.

Since Petya really likes numbers, the first thing he learned was spells for changing numbers. So far, he knows only two spells that can be applied to a positive integer:

If the chosen number a is even, then the spell will turn it into 3a2;
If the chosen number a is greater than one, then the spell will turn it into a−1.
Note that if the number is even and greater than one, then Petya can choose which spell to apply.

Petya now has only one number x. He wants to know if his favorite number y can be obtained from x using the spells he knows. The spells can be used any number of times in any order. It is not required to use spells, Petya can leave x as it is.

输入

The first line contains single integer T (1≤T≤104) — the number of test cases. Each test case consists of two lines.

The first line of each test case contains two integers x and y (1≤x,y≤109) — the current number and the number that Petya wants to get.

输出

For the i-th test case print the answer on it — YES if Petya can get the number y from the number x using known spells, and NO otherwise.

You may print every letter in any case you want (so, for example, the strings yEs, yes, Yes and YES will all be recognized as positive answer).

样例输入

7
2 3
1 1
3 6
6 8
1 2
4 1
31235 6578234

样例输出

YES
YES
NO
YES
NO
YES
YES

解题思路

这是一道我做到一半感觉自己不会就放弃了的题目。
题意就是看前面输入的数经过两种变换能不能变成后面的数,刚开始我以为只能变一次,后来发现可以变很多次,情况就让我有点晕了,后来我就放弃睡觉了。但是第二天我发现大家都写出来了!!居然只有我一个人只写了一题,又丢脸了!!
看了AC的代码,居然那么短就完了!!我在想什么呢!!

程序代码:(改到一半,没改完的WA代码)

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
long long a,b;
int main(){int T;scanf("%d",&T);while(T--){scanf("%d %d",&a,&b);if(a<=b){printf("YES\n");continue;}int flag=0;while(a>b){if(a%2==0){if(a>1){long long t1=3*a/2;long long t2=a-1;if(t2>=b){printf("YES\n");flag=1;break;}else if(t2==b){printf("YES\n");flag=1;break;}else{a=3*a/2;}
//                  else if((t1-1)==b){//                      printf("YES\n");flag=1;break;
//                  }else if((3*t2/2)==b){//                      printf("YES\n");flag=1;break;
//                  }}else{a=3*a/2;if(a==b){printf("YES\n");flag=1;continue;}}}else if(a>1){a=a-1;if(a==b){printf("YES\n");flag=1;break;}}}if(flag==0){printf("NO\n");}}return 0;
}

程序代码:(AC)

#include <bits/stdc++.h>
using namespace std;
bool K(long long x, long long y) {if (x == 1 && y > 1) return false;if (x == 2 && y > 3) return false;if (x == 3 && y > 3) return false;return true;
}
int main() {int t;long long x, y;cin >> t;while (t--) {cin >> x >> y;//cerr << x << ' ' << y << '\n';cout << (K(x, y) ? "yes" : "no") << '\n';}return 0;
}

三、牛客网-四川大学新生赛

1.丁姐喜欢LCS

题意

丁姐姐最近迷上了LCS(The longest common substring)!
今天她想找个其它东西玩,于是她找到了两个字符串A和B,现在她想知道它们尾头衔接形成的最长字符串,例如A = abc,B = bca从A的尾部开始,A串的bc与B串的bc头尾衔接。

输入

输入数据包含多个测试样例,每个测试样例占两行,第一行是字符串A,第二行是字符串B,保证每个字符串的长度不超过1010。

输出

A和B尾头衔接形成的最长字符串,对于每个测试实例,输出一行,若两个字符串不衔接,输出"NULL!"(包含引号)。

样例输入

abc
bca
wad
ad
as
asd
wa
aw
wa
wwa

样例输出

bc
ad
as
a
"NULL!"

解题思路

就是一个个找,如果都一样就是答案,用vector存储,因为它可以直接清空,太方便了。

程序代码

#include<bits/stdc++.h>
using namespace std;
long long n;
int main(){string a,b;while(cin>>a>>b){vector<char>q;int len1=a.length();int len2=b.length();int cnt=0;for(int i=0;i<len1;i++){if(a[i]==b[cnt]){q.push_back(a[i]);cnt++;}else{if(cnt){cnt=0;q.clear();}if(a[i]==b[cnt]){q.push_back(a[i]);cnt++;}   }}if(q.empty()){printf("\"NULL!\"\n");}else{for(int i=0;i<q.size();i++){printf("%c",q[i]);}printf("\n");}}return 0;
}

2.俏兔子大战傻贼鹰-Easy Version

题意

麻蛇更,麻蛇更,麻蛇不更麻蛇羹,麻蛇更麻蛇也羹。
傻贼鹰今天到兔子家做客因为傻贼鹰听说兔子家的四川省四川大学是一所双流一大学,还有很多漂亮的俏兔子。你作为四川大学英语最好的最俏的俏兔子,被安排接待傻贼鹰。傻贼鹰来到四川大学被四川大学ACM集训队的兔子拉着打四川麻将,由于傻贼鹰实在学不会麻将,现在兔子们决定
简化一下规则:
1、只有条(索)、筒(饼)、万三种牌共108张每种牌36张(一二三四五六七八九各4张),没有花、风牌和箭牌。
2、必须缺一门可胡且开局确定缺哪一门,即胡牌的时候不能有三种花色的牌。
3、不允许鸣牌(吃碰杠)
4、刻子:三张同样的牌如(一筒一筒一筒)
5、一对将:两张完全相同的牌如(一条一条)
胡牌规则:
1、对对胡:四副刻子加一对将
2、七对子:七对一模一样的牌(缺索:一万一万二万二万一筒一筒三筒三筒五筒五筒六筒六筒九筒九筒)
即使简化了规则,傻贼鹰还是学不会,所以就求你告诉他是不是能胡牌,如果能胡牌你就要用你那专业的英语告诉他Yes,不能胡牌你就要告诉他No

输入

有多组数据,每组数据第一行是N(1\le N\le 10)N(1≤N≤10),表示这一局傻贼鹰对你询问了N次。
第二行是一个大写字母(T:表示筒(饼),S:表示索(条),W:表示万),用来表示定缺牌。
接下来N行每行一个字符串用来表示询问是否能胡的14张牌的信息。
比如:1W1W2W2W1T1T3T3T5T5T6T6T9T9T
表示:一万一万二万二万一筒一筒三筒三筒五筒五筒六筒六筒九筒九筒

输出

对于傻贼鹰的每一次询问,如果能胡牌输出Yes,不能胡牌输出No。

样例输入

5
S
1W1W2W2W1T1T3T3T5T5T6T6T9T9T
1W1W2W2W1T1T3T3T5T5T6T6T9S9S
8T9T1W3W4W5T8T2W8T9T5T5T5W6W
1W2W2W1W3W3W3W9S1W1W2W2W3W9S
3W3W3W5W5W5W6W6W6W7W7W9W9W9W
1
T
2W3W1W1S2S2W2W3W2S1W1W3W1S1S

样例输出

Yes
No
No
No
Yes
Yes

解题思路

每次读进去都让相应的数组加一,最后按找胡牌的规则遍历一遍就可以了

程序代码

#include<bits/stdc++.h>
using namespace std;
int w[10],t[10],s[10];
int main(){int T;char q;while(~scanf("%d %c",&T,&q)){while(T--){memset(w,0,sizeof(w));memset(t,0,sizeof(t));memset(s,0,sizeof(s));string str;cin>>str;int len=str.length();int temp,flag=1;for(int i=0;i<len;i++){if(i%2==0){temp=str[i]-'0';}else{if(str[i]==q){flag=0;break;}else if(str[i]=='W'){w[temp]++;}else if(str[i]=='T'){t[temp]++;}else if(str[i]=='S'){s[temp]++;}}}if(flag==0){printf("No\n");}else{int flag2=0,flag3=0;for(int i=1;i<=9;i++){if(w[i]==2){flag2++;}else if(w[i]==3){flag3++;}}for(int i=1;i<=9;i++){if(t[i]==2){flag2++;}else if(t[i]==3){flag3++;}}for(int i=1;i<=9;i++){if(s[i]==2){flag2++;}else if(s[i]==3){flag3++;}}if((flag2==7)||(flag2==1&&flag3==4)){printf("Yes\n");}else{printf("No\n");}}}}return 0;
}

3.俏兔子大战傻贼鹰-Hard Version

题意

麻蛇更,麻蛇更,麻蛇不更麻蛇羹,麻蛇更麻蛇也羹。
傻贼鹰今天到兔子家做客因为傻贼鹰听说兔子家的四川省四川大学是一所双流一大学,还有很多漂亮的俏兔子。你作为四川大学英语最好的最俏的俏兔子,被安排接待傻贼鹰。 傻贼鹰来到四川大学被四川大学ACM集训队的兔子拉着打四川麻将,由于傻贼鹰实在学不会麻将,现在兔子们决定复杂一下简单的规则:
1、只有条(索)、筒(饼)、万三种牌共108张每种牌36张(一二三四五六七八九各4张),没有花、风牌和箭牌。
2、必须缺一门可胡且开局确定缺哪一门,即胡牌的时候不能有三种花色的牌。
3、不允许鸣牌(吃碰杠)
4、坎牌:三张连续的同种牌如(一万二万三万),三张同样的牌如(一筒一筒一筒)
5、一对将:两张完全相同的牌如(一条一条)
胡牌规则:
1、平胡:四坎牌加一对将
2、七对子:七对一模一样的牌(缺索:一万一万二万二万一筒一筒三筒三筒五筒五筒六筒六筒九筒九筒) 即使简化了规则,傻贼鹰还是学不会,所以就求你告诉他是不是能胡牌,如果能胡牌你就要用你那专业的英语告诉他Yes,不能胡牌你就要告诉他No

输入

输入有多组数据,每组数据第一行是N(1\le N\le10)(1≤N≤10)表示这一局傻贼鹰对你询问了N次。

第二行是一个大写字母(T:表示筒(饼),S:表示索(条)W,表示万)用来表示定缺牌。

接下来N行,每行一个字符串用来表示询问是否能胡的14张牌的信息。

比如:1W1W2W2W1T1T3T3T5T5T6T6T9T9T
表示:一万一万二万二万一筒一筒三筒三筒五筒五筒六筒六筒九筒九筒

输出

对于傻贼鹰的每一次询问,如果能胡牌输出Yes,不能胡牌输出No。

样例输入

5
S
1W1W2W2W1T1T3T3T5T5T6T6T9T9T
1W1W2W2W1T1T3T3T5T5T6T6T9S9S
8T9T1W3W4W5T8T2W8T9T5T5T5W6W
1W2W2W1W3W3W3W9S1W1W2W2W3W9S
3W3W3W3W4W5W6W6W6W7W8W9W9W9W
1
T
1W3W1S1S2S1W2W1W3W2S3S3S2W1W

样例输出

Yes
No
Yes
No
Yes
Yes

解题思路

这题是上题的进阶版,多了一个条件,当时我就没写这道题了,因为加了一个条件我有点不知道如何写,没什么思路,比赛结束后看了别人的代码。

程序代码

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>typedef long long LL;
using namespace std;int n;
char s[2], str[25];
int num[3][10];int main()
{//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);while(scanf("%d", &n) == 1){scanf("%s", s);for (int i = 1; i <= n; i++){memset(num, 0, sizeof(num));scanf("%s", str);int f = 0;for (int i = 0; i < 28; i++){if(str[i] == s[0]) {f = 1; break;}}if(f) {printf("No\n"); continue;}for (int i = 1; i < 28; i += 2){if(str[i] == 'W') num[0][str[i - 1] - '0']++;else if(str[i] == 'T') num[1][str[i - 1] - '0']++;else num[2][str[i - 1] - '0']++;// printf("%c\n", str[i - 1]);}int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;for (int i = 0; i < 3; i++){for (int j = 1; j <= 9; j++){if(num[i][j] == 2) sum1++;}}for (int i = 0; i < 3; i++){for (int j = 1; j <= 7; j++){while(num[i][j] > 0 && num[i][j + 1] > 0 && num[i][j + 2] > 0){sum3++;num[i][j]--, num[i][j + 1]--, num[i][j + 2]--;// printf("%d\n", j);}}}for (int i = 0; i < 3; i++){for (int j = 1; j <= 9; j++){if(num[i][j] == 3) sum4++;else if(num[i][j] == 2) sum2++;}}// printf("%d %d %d %d\n", sum1, sum2, sum3, sum4);if(sum1 == 7 || (sum2 == 1 && (sum4 + sum3 == 4))) printf("Yes\n");else printf("No\n");}}return 0;
}

4.欧拉筛

题意

lglg最近爱上了炒股,他想在股票市场内买一些股票。

现在有编号为1,2,3,…,100000000的100000000支股票,每个股票的价值等于其编号的阶乘(例如编号为5的股票的价值就是120)。
lglg是一个很挑剔的人,他只喜欢编号为质数的股票,但他很有钱,因此他希望买下所有编号小于等于N(1<=N<=1e8)并且编号为质数的股票,请你帮他算一算这些股票的价值之和。

由于价值和很大,他希望你能告诉他价值之和对P(1e3<=P<=1e5)取模后的值。

输入

输入包含多组数据 第一行是一个正整数 T(1<=T<=1000),代表数据的组数。

每组数据只有一行,包含两个正整数 N 和 P 数字之间用空格隔开,其代表的含义及范围已在题面中给出。

输出

每组数据输出一行,表示lglg希望买下的所有股票的价值之和对P取模后的值

样例输入

2
5 1001
20 1001

样例输出

128
86

解题思路

这题我改了好久好久,去网上找了欧拉筛的模板,然后还要算阶乘,而且数据还很大,最后的结果就是超内存了,想先把数据改小试试,结果超时了,我的失败代码!!做题真是太难了!!

程序代码:(RE和超内存)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int n,ans=0;
int p;
int prime[N+5];
int visit[N+5];
void Prime(){//    memset(visit,sizeof(visit),0);
//    memset(prime,sizeof(prime), 0);for (int i = 2;i <= N ; i++) {//        cout<<" i = "<<i<<endl;if (!visit[i]) {prime[++prime[0]] = i;      //纪录素数, 这个prime[0] 相当于 cnt,用来计数}for (int j = 1; j <=prime[0] && i*prime[j] <= N; j++) {//            cout<<"  j = "<<j<<" prime["<<j<<"]"<<" = "<<prime[j]<<" i*prime[j] = "<<i*prime[j]<<endl;visit[i*prime[j]] = 1;if (i % prime[j] == 0) {break;}}}
}
int f(int n){int t=1;for(int i=2;i<=n;i++){//      t=(t*i)%p;t=((t%p)*(i%p))%p;}return t;
}
int main(){Prime();
//  cout<<visit[4]<<endl;int T;scanf("%d",&T);while(T--){scanf("%d %d",&n,&p);ans=0;for(int i=2;i<=n;i++){if(!visit[i]){//              cout<<i;
//              cout<<i<<" "<<f(i)<<endl;ans=(ans%p+f(i)%p)%p;}}
//      printf("\n");printf("%d\n",ans%p);} return 0;
}

程序代码:(AC)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
int prime[N],cnt;
bool vis[N];
void init()
{vis[1]=true;for(int i=2;i<N;i++){if(!vis[i])prime[cnt++]=i;for(int j=0;j<cnt&&i*prime[j]<N;j++){vis[i*prime[j]]=1;if(i%prime[j]==0)break;}}
}
int main()
{init();int t;scanf("%d",&t);while(t--){ll n,p,sum=1,ans=0;cin>>n>>p;for(int i=1;i<=min(n,p);i++){sum=(sum*i)%p;if(!vis[i])ans=(ans+sum)%p;}cout<<ans<<endl;}
}

5.后缀自动机

题意

这是一道模板题:给定两个字符串S和T,询问S中是否存在一个后缀P,使得T的任何一个前缀的字典序都大于P。
注意:数据里同时含有大写与小写字母,比较字典序时严格按照 Ascii 编码进行比较,即我们认为 A<B<C…<Z<a<b<c<…<z 。

输入

每组数据有两行只包含英文字母的字符串,第一行是S,第二行是T (0< |S|,|T|<=2*10^5)

输出

每组数据输出一行,若存在这样的P,输出“YE5”,否则输出“N0”(不带引号).

样例输入

3
lglg
rzynb
zzytql
dalaoddw
uiyouivyziuoxcovzuncuiasdaisdb
yzvuihouvsfvdjsausnnuncvviasudalsky

样例输出

YE5
N0
YE5

解题思路

只用找第一个字符串中最小的字符,然后看第二个字符串中的第一个是不是比他大就行了。

程序代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{char s[200005],t[200005],c;int n;cin>>n;while(n--){cin>>s>>t;c=s[0];for(int i=1;i<strlen(s);i++)if(c>s[i])c=s[i];                   //找s中最小字符 if(c<t[0])cout<<"YE5"<<endl;         //是否存在一个后缀P,使得T的任何一个前缀的字典序都大于P。else cout<<"N0"<<endl;}return 0;
}

6.双流机场

题意

众所周知,双流机场是一座庞大的现代化国际机场。
双流机场中间修建有很多自动人行扶梯,这些扶梯纵横交错,分为纵横两种,双流机场一共有n条纵向扶梯(每条纵向扶梯只能固定的朝上或者是朝下运输行人),m条横向扶梯(每条横扶梯只能固定朝左或者是朝右运输行人),小魏从双流机场的管理人员那儿得知了这些纵横交错的扶梯的运输方向(具体排布如样例所示)。
大家都知道站在机场的扶梯上是一件特别爽的事情,但是可能我们从某些扶梯的交点(下文简称为某些点)出发只走扶梯不能到达某些点,所以小魏的问题就来了:他能否从任何点出发通过扶梯到达任何点?(为了小魏的安全着想,小魏在只能在扶梯上站着不动,或者是在交界处走上另外一个扶梯,而不能逆行,逆行太危险了)
如果可以小魏会很开心请输出“Happy”,否则他会很伤心请输出“Sad”(没有引号)

输入

第一行输入一个正整数T(T<20)代表有 T 组数据
对于每一组数据:
第一行输入两个正整数 n,m(2<=n,m<=10^5)
第二行输入 n 个 0 或者是 1 , 0 代表该扶梯向下运输行人, 1 代表该扶梯向上运输行人 ,从左往右 n 个 0,1 代表从从左往右 n 个自动扶梯的走向。
第三输入 m 个 0 或者是 1 , 0 代表该扶梯向左运输行人, 1 代表该扶梯向右运输行人 ,从左往右 m 个 0,1 代表从从上往下 m 个自动扶梯的走向。

输出

每行输出一个“Happy”或者是“Sad”(没有引号)。

样例输入

2
3 3
010
010
3 3
011
011

样例输出

Sad
Happy

解题思路

这题说是签到题,这可激起了我的胜负欲,结果居然没写出来。
我已经想到只用考虑四个角了,但是居然还是错了,明明我想的很周到啊,只要四个角的出度和入度一样就可以,但是WA了,我也伤心了。最后是别人的我觉得考虑不周到的居然对了,真是让人生气。
看了题解,我觉得我也没错啊!!!气死我了
我好像知道哪里错了,应该是不一定等于我给的值,只要一样就可以了!

程序代码:(WA)

#include<bits/stdc++.h>  //WA
using namespace std;
int main(){int T;scanf("%d",&T);while(T--){int n,m;scanf("%d %d",&n,&m);string a,b;cin>>a>>b;if((a[0]-'0'+b[0]-'0'==0)&&(a[n-1]-'0'+b[m-1]-'0'==2)&&(a[0]-'0'+b[m-1]-'0'==1)&&(a[n-1]-'0'+b[0]-'0'==1)){printf("Happy\n");}else{printf("Sad\n");}}return 0;
}

程序代码:(AC)

#include<bits/stdc++.h>
using namespace std;
int main(){int T;cin>>T;while(T--){int b,c;cin>>b>>c;string s,t;cin>>s>>t;if(s[0]=='1'&&t[0]=='0')cout<<"Sad"<<endl;else if(s[0]=='0'&&t[c-1]=='0')cout<<"Sad"<<endl;else if(s[b-1]=='1'&&t[0]=='1')cout<<"Sad"<<endl;else if(s[b-1]=='0'&&t[c-1]=='1')cout<<"Sad"<<endl;elsecout<<"Happy"<<endl;}
}

程序代码:(题解AC)

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
char s[maxn], t[maxn];
int main() {int T; cin>>T;while(T--) {int n, m; cin>>n>>m;cin>>s>>t;if(s[0] == t[0] && s[n-1] == t[m-1] && s[0] != s[n-1])cout<<"Happy"<<endl;elsecout<<"Sad"<<endl;}return 0;
}

7.n=abc

题意

给你一个整数 n(1<=n<=100000), 请你将其拆成三个整数 a,b,c (1<a<=b<=c<n), 的乘积,要求 c-a 尽可能小,在此前提下,a 也尽可能小。

输入

第一行一个整数 T(1<=T<=1000) 表示数据组数。
对于每组数据,一个整数 n(1<=n<=100000) 。

输出

如果可以拆成三个整数的乘积,输出一行形如 n=abc 的信息,其中 a,b,c 按升序排列。
如果不能拆成三个整数的乘积,输出 No solution 。

样例输入

2
12
10

样例输出

12=2*2*3
No solution

程序代码

#include<bits/stdc++.h>
using namespace std;
const int inf=1e9;
int book[100001];
int main()
{for(int i=2;i<=100001;i++){for(int j=2;j*j<=i;j++){if(i%j==0)book[i]=i/j;}}int T;cin>>T;int n;while(T--){cin>>n;int a=0,b=0,c=0;int u=inf;for(int i=2;i*i<=n;i++){if(n%i==0){if(book[n/i]==0)continue;else{int d=i,f=book[n/i],e=n/i/book[n/i];if(d<=e&&e<=f){if(f-d<u){a=d;b=e;c=f;u=c-a;}else continue;}}}}if(u==inf)cout<<"No solution"<<endl;else{cout<<n<<"="<<a<<"*"<<b<<"*"<<c<<endl;}}return 0;
}

四、PTA

1.括号匹配

题意

给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。

输入

输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。

输出

如果括号配对,输出yes,否则输出no。

样例输入

sin(10+20)

样例输出

yes

解题思路

用STL中的栈做,就是一定要注意,每次出栈前要判断栈是否为空,如果没判断就会出错!!

程序代码

#include<bits/stdc++.h>
using namespace std;
int main(){stack<char>s;string str;getline(cin,str);int len=str.length();int flag=1; for(int i=0;i<len;i++){if(str[i]=='('||str[i]=='['||str[i]=='{'){s.push(str[i]);}else if(str[i]==')'){if(!s.empty()&&s.top()=='('){s.pop();}else{flag=0;break;}}else if(str[i]==']'){if(!s.empty()&&s.top()=='['){s.pop();}else{flag=0;break;}}else if(str[i]=='}'){if(!s.empty()&&s.top()=='{'){s.pop();}else{flag=0;break;}}}if(flag&&s.empty()){printf("yes\n");}else{printf("no\n");}return 0;
}

2.堆栈操作合法性

题意

假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。

输入

输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过100。

输出

对每个序列,在一行中输出YES如果该序列是合法的堆栈操作序列,或NO如果不是。

样例输入

4 10
SSSXXSXXSX
SSSXXSXXS
SSSSSSSSSSXSSXXXXXXXXXXX
SSSXXSXXX

样例输出

YES
NO
NO
NO

程序代码

#include<bits/stdc++.h>
using namespace std;
int main(){int n,m;cin>>n>>m;for(int i=1;i<=n;i++){string s;cin>>s;int len=s.length();stack<char>a;int flag=1;for(int j=0;j<len;j++){if(a.size()>m){flag=0;break;}if(s[j]=='S'){a.push('S');}else{if(!a.empty()){a.pop();}else{flag=0;break;}}}if(flag && a.empty()){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}}return 0;
}

3.汉诺塔的非递归实现

题意

借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。

输入

输入为一个正整数N,即起始柱上的盘数。

输出

每个操作(移动)占一行,按柱1 -> 柱2的格式输出。

样例输入

3

样例输出

a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c

解题思路

虽然要求用非递归方式,但是我不会,就用了递归方式。

程序代码

#include <stdio.h>
#include <string.h>
void move(char x,char y)
{printf("%c -> %c\n",x,y);
}
void hannuo(int n,char one ,char two,char three)
{if(n==1)move(one, three);else{hannuo(n-1,one ,three,two);move(one,three);hannuo(n-1,two,one,three);}
}
int main()
{int n;scanf("%d",&n);hannuo(n,'a','b','c');return 0;
}

小陈的开学第十周程序相关推荐

  1. C语言编程>第二十周 ② 下列给定程序中,函数fun的功能是:求出数组中最大数和次最大数,并把最大数和b[0]中的数对调、次最大数和b[1]中的数对调。

    例题:下列给定程序中,函数fun的功能是:求出数组中最大数和次最大数,并把最大数和b[0]中的数对调.次最大数和b[1]中的数对调. 注意:不要改动main函数,不能增行或删行,也不能更改程序的结构. ...

  2. 20165301第十周课下补做

    第十周课下补做 知识点总结 创建一个空的链表 List<Student> list = new LinkedList<Student>(); 向链表中添加新的结点 list.a ...

  3. 2019春第十周作业

    第十周作业 本周作业头 这个作业属于哪个教程 C语言程序设计Ⅱ 这个作业要求在哪里 (https://edu.cnblogs.com/campus/zswxy/software-engineering ...

  4. 20155230 2016-2017-2 《Java程序设计》第十周学习总结

    20155230 2016-2017-2 <Java程序设计>第十周学习总结 教材学习内容总结 网络编程:就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发 ...

  5. # 20155337 2016-2017-2 《Java程序设计》第十周学习总结

    20155337 2016-2017-2 <Java程序设计>第十周学习总结 教材学习内容总结 网络编程 •网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就 ...

  6. 20145302张薇《Java程序设计》第十周学习总结

    20145302 <Java程序设计>第十周学习总结 客户端和服务器端功能 客户端程序功能列表: 接收用户控制台输入 判断输入内容是否合法 按照协议格式发送数据 根据服务器端的反馈给出相应 ...

  7. “海大与我“ Scrum Meeting(第十周会议记录)

    "海大与我" Scrum Meeting(第十周会议记录) 一.工作汇报 姓名 已完成工作 计划完成工作 谢禄青 优化界面,并实现与数据库的链接,能够实现用户简单方便地进行文件的上 ...

  8. “海大学舍”Scrum Meeting(第十周会议记录)

    Alpha阶段结束后,有些松懈,第九周没有实质性进展.小组从第十周开始Beta阶段冲刺 一.小组工作汇报 小组成员 已完成 计划完成 董丽博 查找并显示存储文件获取存储数据 实现"我的发布& ...

  9. linux学习第十周总结

    linux学习第十周总结 接着上周的mysql,重点终结日志管理 ,备份还原,主从复制和mysql集群 一.mysql日志管理 事务日志 transaction log 错误日志 error log ...

最新文章

  1. 童心未泯的 YOLO 之父,小马哥 Joseph Redmon 笑傲 CV 江湖记
  2. @Data 注解对类静态字段, 无效
  3. 前20个关于FLEX技术、源码、实例、技巧的网站.
  4. 小android模拟器,小姚Android模拟器工作室版本v6.2.7.0正式版
  5. 为什么要使用服务器信号切换器,为何要使用KVM切换器,其好处有哪些
  6. 关于分行数字化转型工作的几点思考
  7. 谷歌浏览器html调试iphone11,FireFox chrome 模拟手机浏览器 调试手机网页
  8. Python在Linux环境下Word转PDF
  9. 按图搜索商品获取数据测试
  10. 个税汇算清缴是怎么算的,为何有人补税几百,有人退税几千?
  11. 微型计算机pcu,浅谈丰田紧凑型HV动力控制单元(下)
  12. 安卓手机开机动画制作修改教程
  13. 浙江工业大学计算机应用基础,本科教学-浙江工业大学计算机科学与技术.doc
  14. Windows2008开启telnet命令的方法
  15. 2021工资翻倍指南:Android面经,历时一个半月,斩获3个大厂offer
  16. 艾永亮:流量,营销,爆款连连失效,餐饮业如何逃离三年倒闭的魔咒?
  17. php symfony 安装,安装和设置Symfony框架
  18. Java NIO 基本原理以及三大核心组件
  19. SPSS新手教学——如何进行ROC分析
  20. python 制作 艾宾浩斯记忆表

热门文章

  1. App Store付费排行榜第一的杀毒软件竟暗藏间谍功能
  2. Matlab 三维装箱遗传算法实现
  3. ES6(二)解构赋值
  4. Java执行定时任务,和指定时间完成任务
  5. 微信用户ios android比例,微信号可以修改了!Android 版正全量上线,iOS 也快了
  6. jboss hornetq jms 用户文档
  7. mysql如何实现自增序列
  8. [油猴脚本开发指南]h5视频倍速,时间加速和run-at
  9. 应收、应付、预收、预付 会计分录
  10. NLP04:LSTM原理详解及文本生成