NCST 2018-2019秋季学期17级个人排位赛(四)
A : Sorting Pairs
Time Limit:2.000 Sec Memory Limit:128 MiB
Description
写一个程序,对\(n\)个点的坐标\((X_i,Y_i)\)进行排序,\(1 \leqslant n \leqslant 1000\)
排序的规则首先按照\(X\)坐标升序排序,在\(X\)坐标相等的情况下,按\(Y\)坐标升序排序
Input
输入按以下形式进行:
n
x0 y0
x1 y1
:
xn−1 yn−1
输入的第一行\(n\)代表坐标点的个数,下面\(n\)行为每个坐标点的坐标
Output
输出排序后的坐标,每个坐标占一行
Sample Input
5
4 7
5 5
2 3
6 8
2 1
Sample Output
2 1
2 3
4 7
5 5
6 8
- TAG:排序
cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
int x,y;
}s[1005];
bool cmp(node a,node b){ return a.x==b.x ? a.y<b.y : a.x<b.x; }
int n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d %d",&s[i].x,&s[i].y);
sort(s+1,s+1+n,cmp);
for(int i=1;i<=n;++i) printf("%d %d\n",s[i].x,s[i].y);
return 0;
}
B : Count Substrings
Time Limit:2.000 Sec Memory Limit:128 MiB
Description
给你两个由\(0\)和\(1\)组成的字符串\(A,B\),请你判断\(B\)中含有\(A\)的数目。
例如:
字符串\(A\):01
字符串\(B\):01000101
则\(B\)中由\(3\)个\(A\)。
Input
输入的第一行为一个整数\(N\),代表有\(N\)组测试数据。
每组测试数据含有两行,第一行为字符串\(A\),第二行为字符串\(B\)。
规定:\(A\)与\(B\)的长度均不超过\(1000\)。
Output
输出字符串\(B\)中含有字符串\(A\)的数目。
Sample Input
3
11
1001110110
101
110010010010001
1010
110100010101011
Sample Output
3
0
3
- TAG:字符串
cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
string A,B;
int N,ans;
bool check_str(string x,string y,int X){
int j=0;
for(int i=X;i<y.size();++i){
if(y[i]!=x[j]) return 0;
++j;
if(j==x.size()) break;
}
if(j!=x.size()) return 0;
return 1;
}
int main(){
scanf("%d",&N);
while(N--){
ans=0;
cin>>A>>B;
for(int i=0;i<B.size();++i){
if(check_str(A,B,i)) ++ans;
}
printf("%d\n",ans);
}
return 0;
}
C : 抽样检查
Time Limit:5.000 Sec Memory Limit:128 MiB
Description
\(A\)公司生产了很多很多不同类型的产品,每个产品都有自己的编号\(i(0\leqslant i \leqslant 100000000)\),编号不连续,同样的产品有相同的编号。
产品上市前需要做抽样检查,监察员会随机选择一个编号\(k(0\leqslant k \leqslant 100000100)\),请你帮忙写个程序,帮监察员判断编号为\(k\)的产品是否存在(存在为YES
,否则为NO
)。
Input
第一行有两个整数\(m,n(0\leqslant m \leqslant 1000000 , 0 \leqslant n \leqslant 100000)\);\(m\)表示\(A\)公司生产了\(m\)个产品,\(n\)表示监察员需要你帮忙进行\(n\)次判断。
第二行为\(m\)个数,分别代表全部\(m\)个产品的编号。
第三行为\(n\)个数,分别代表\(n\)次判断中的编号。
Output
输出YES
或NO
Sample Input
6 4
23 34 46 768 343 343
2 4 23 343
Sample Output
NO
NO
YES
YES
-
这里直接使用
map
这一\(STL\)解决; -
TAG:模拟;map
cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int m,n,x;
map<int,int>vis;
int main(){
scanf("%d %d",&m,&n);
while(m--){
scanf("%d",&x);
vis[x]=1;
}
while(n--){
scanf("%d",&x);
if(vis[x]) puts("YES");
else puts("NO");
}
return 0;
}
D : 众数与重数
Time Limit:2.000 Sec Memory Limit:128 MiB
Description
众数:元素集合中出现次数最多的元素。
重(chóng)数:元素集合中众数出现的次数。
例如:\(S=\{1,2,2,2,3\}\),则集合\(S\)的众数是\(2\),其重数为\(3\)。
请你计算一个集合的众数与重数。
Input
第一行为\(n\),表示测试数据组数。\((n<30)\)。
每组测试数据的第一行是一个整数\(m\),表示多重集\(S\)中元素的个数为\(m\)。
每组测试数据的第二行为\(m(m<10^6)\)个不大于\(10^9\)的自然数。
(不会出现不同元素出现的次数相同的情况,如:\(S=\{1,1,2,2\}\)。)
Output
输出每组测试数据输出众数与重数,中间以空格隔开。
Sample Input
1
5
1 2 2 2 3
Sample Output
2 3
More Info
数组最多开到\(10^7\),本题数据范围\(10^9\)过大,使用数组需谨慎
-
这里直接使用
map
这一\(STL\)解决; -
TAG:数学;map
cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#include<map>
using namespace std;
int n,m,x,ans,maxx,res;
int main(){
scanf("%d",&n);
while(n--){
map<int,int>vis;
maxx=-INT_MAX;
scanf("%d",&m);
while(m--){
scanf("%d",&x);
res=++vis[x];
maxx < res ? ans=x,maxx=res: 233;
}
printf("%d %d\n",ans,maxx);
}
return 0;
}
E : 递归函数
Time Limit:1.000 Sec Memory Limit:64 MiB
Description
我们都爱递归!比如这样一个递归函数:
FUNCTION w(a, b, c):
IF x ≤ 0 or y ≤ 0 or z ≤ 0, THEN w(x, y, z) RETRNS : 1
IF x > 20 or y > 20 or z > 20, THEN w(x, y, z) RETURNS : w(20, 20, 20)
ELSE IF x < y and y < z, THEN w(x, y, z) RETURNS: w(x, y, z-1) + w(x, y-1, z-1) - w(x, y-1, z)
ELSE w(x, y, z) RETURNS:w(x-1, y, z) + w(x-1, y-1, z) + w(x-1, y, z-1) - w(x-1, y-1, z-1)
数据规模约定:
\(0 < x,y,z < 100\)
Input
输入包含多条测试数据,每条测试数据包含\(3\)个整数:\(x,y,z\)。
输入以-1 -1 -1
结束。
Output
对每条测试数据,按照Sample Output的格式 输出函数的值。
Sample Input
1 1 1
2 2 2
10 4 6
-1 7 18
-1 -1 -1
Sample Output
w(1, 1, 1) = 2
w(2, 2, 2) = 4
w(10, 4, 6) = 523
w(-1, 7, 18) = 1
Solution
1.这里使用 记忆化搜索,简单来说就是把每次搜索到的w(x,y,z)
都记录下来,这样可以节省大量递归时间;
2.不过这题数据出的不严谨,明明\(0 < x,y,z < 100\),但样例中还是有\(-1\)的存在,所以对于IF x ≤ 0 or y ≤ 0 or z ≤ 0, THEN w(x, y, z) RETRNS : 1
这一句需要特判;
- TAG:记忆化搜索
std.cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int W[105][105][105];
int w(int x,int y,int z){
if(x<=0||y<=0||z<=0) return 1;
if(W[x][y][z]) return W[x][y][z];
if(x>20||y>20||z>20) return W[x][y][z]=w(20,20,20);
else if(x<y && y<z) return W[x][y][z]=w(x,y,z-1)+w(x,y-1,z-1)-w(x,y-1,z);
else return W[x][y][z]=w(x-1,y,z)+w(x-1,y-1,z)+w(x-1,y,z-1)-w(x-1,y-1,z-1);
}
int main(){
int x,y,z;
while(scanf("%d %d %d",&x,&y,&z)&&!(x==-1&&y==-1&&z==-1)){
printf("w(%d, %d, %d) = %d\n",x,y,z,w(x,y,z));
}
return 0;
}