#1. A+B
给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开。 现在请计算A+B的结果,并以正常形式输出。
输入描述:
输入包含多组数据数据,每组数据占一行,由两个整数A和B组成(-10^9 < A,B < 10^9)。
输出描述:
请计算A+B的结果,并以正常形式输出,每组数据占一行。
输入样例:
-234,567,890 123,456,789
1,234 2,345,678
输出样例:
-111111101
2346912
#include <iostream>
using namespace std;
typedef long long ll;
int main(){
string a,b;
while(cin>>a>>b){
ll aa = 0,bb=0;
int len1 = a.size(),len2 = b.size();
ll p1 =1,p2 =1;
for(int i =0;i<len1;i++)
{
if(a[i]==',')
continue;
if(a[i]=='-'){
p1 = -1;
continue;
}
aa = aa*10+a[i]-'0';
}
aa*=p1;
for(int i =0;i<len2;i++)
{
if(b[i]==',')
continue;
if(b[i]=='-'){
p2 = -1;
continue;
}
bb = bb*10+b[i]-'0';
}
bb*=p2;
cout<<aa+bb<<endl;
}
return 0;
}
又一版 A+B
输入两个不超过整型定义的非负10进制整数A和B(<=231-1),输出A+B的m (1 < m <10)进制数。
输入描述:
输入格式:测试输入包含若干测试用例。每个测试用例占一行,给出m和A,B的值。
当m为0时输入结束。
输出描述:
输出格式:每个测试用例的输出占一行,输出A+B的m进制数。
输入样例:
8 1300 48
2 1 7
0
输出样例:
2504
1000
#include<bits/stdc++.h>
using namespace std;
//typedef long long ll;
int main()
{
int m;
while(scanf("%d",&m)!=EOF && m){
// ll a=0,b=0,sum = 0;
int a=0,b=0,sum = 0;
scanf("%d %d",&a,&b);
sum=a+b;
vector<int> ret;
if(sum==0)
ret.push_back(0);
else{
while(sum!=0){
ret.push_back(sum%m);
sum/=m;
}
}
for(int i =ret.size()-1;i>=0;i--)
{
cout<<ret[i];
}
cout<<endl;
}
return 0;
}
#2. 还是A+B
读入两个小于10000的正整数A和B,计算A+B。需要注意的是:如果A和B的末尾K(不超过8)位数字相同,请直接输出-1。
输入描述:
测试输入包含若干测试用例,每个测试用例占一行,格式为"A B K",相邻两数字有一个空格间隔。当A和B同时为0时输入结束,相应的结果不要输出。
输出描述:
对每个测试用例输出1行,即A+B的值或者是-1。
输入样例:
1 2 1
11 21 1
108 8 2
36 64 3
0 0 1
输出样例:
3
-1
-1
100
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b,k;
while(scanf("%d %d %d",&a,&b,&k)!=EOF && (a!=0 || b!=0)){
int ret = -1;
for(int i = 0;i<k;i++)
{
if(a%10==b%10){
a/=10;
b/=10;
continue;
}
else
{
ret = a+b;
break;
}
}
cout<<ret<<endl;
}
return 0;
}
加强版A+B
读入两个小于100的正整数A和B,计算A+B. 需要注意的是:A和B的每一位数字由对应的英文单词给出.
输入描述:
测试输入包含若干测试用例,每个测试用例占一行,格式为"A + B =",相邻两字符串有一个空格间隔.当A和B同时为0时输入结束,相应的结果不要输出.
输出描述:
对每个测试用例输出1行,即A+B的值.
输入样例:
one + two =
three four + five six =
zero seven + eight nine =
zero + zero =
输出样例:
3
90
96
#include<stdio.h>
#include<string.h>
//using namespace std;
char num[10][10] = {"zero","one","two","three","four","five","six","seven","eight","nine"};
int e2n(char* s){
int a;
for (a=0;a<10;a++)
if(strcmp(s,num[a])==0)
break;
return a;
}
char str[100];
int main()
{
while(1){
int a=0,b=0;
while(scanf("%s",str)!=EOF && strcmp(str,"+")!=0)
a = a*10+e2n(str);
while(scanf("%s",str)!=EOF && strcmp(str,"=")!=0)
b = b*10+e2n(str);
if(a==0 && b==0) break;
printf("%d\n",a+b);
// cout<<a+b<<endl;
}
return 0;
}
#3. 火星A+B
整数A和B,计算A+B。需要注意的是:在火星上,整数不是单一进制的,第n位的进制就是第n个素数。例如:地球上的10进制数2,在火星上记为“1,0”,因为火星个位数是2进制的;地球上的10进制数38,在火星上记为“1,1,1,0”,因为火星个位数是2进制的,十位数是3进制的,百位数是5进制的,千位数是7进制的……
输入描述:
测试输入包含若干测试用例,每个测试用例占一行,包含两个火星正整数A和B,火星整数的相邻两位数用逗号分隔,A和B之间有一个空格间隔。当A或B为0时输入结束,相应的结果不要输出。
输出描述:
对每个测试用例输出1行,即火星表示法的A+B的值。
输入样例
1,0 2,1
4,2,0 1,2,0
1 10,6,4,2,1
0 0
输出样例:
1,0,1
1,1,1,0
1,0,0,0,0,0
#include<bits/stdc++.h>
using namespace std;
int m[25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51,53,57,59,61,67,71,73,79,83};
int main(){
string a,b;
while(cin>>a>>b)
{
vector<int>aa,bb,cc;
int temp = 0;
for(int i =0;i<a.size();i++)
{
if(a[i]!=',')
{
temp = temp*10+a[i]-'0';
}
else
{
aa.push_back(temp);
temp = 0;
}
}
aa.push_back(temp);
temp = 0;
for(int i =0;i<b.size();i++)
{
if(b[i]!=',')
{
temp = temp*10+b[i]-'0';
}
else
{
bb.push_back(temp);
temp = 0;
}
}
bb.push_back(temp);
if(aa.size()==1 && aa[0]==0) break;
if(bb.size()==1 && bb[0]==0) break;
int count=0;
while(aa.size() || bb.size())
{
int ta=0,tb=0;
if(aa.size())
{
ta = aa[aa.size()-1];
aa.pop_back();
}
if(bb.size())
{
tb = bb[bb.size()-1];
bb.pop_back();
}
cc.push_back((ta+tb)%m[count]);
if((ta+tb)>=m[count])
{
if(aa.size())
{
aa[aa.size()-1]+=1;
}
else{
if(bb.size())
bb[bb.size()-1]+=1;
else
cc.push_back(1);
}
}
count++;
}
cout<<cc[cc.size()-1];
cc.pop_back();
while(cc.size()){
cout<<","<<cc[cc.size()-1];
cc.pop_back();
}
cout<<endl;
}
return 0;
}
#4 .A+B for Matrices
输入描述:
The input consists of several test cases, each starts with a pair of positive integers M and N (≤10) which are the number of rows and columns of the matrices, respectively. Then 2*M lines follow, each contains N integers in [-100, 100], separated by a space. The first M lines correspond to the elements of A and the second M lines to that of B.
The input is terminated by a zero M and that case must NOT be processed.
输出描述:
For each test case you should output in one line the total number of zero rows and columns of A+B.
输入样例:
2 2
1 1
1 1
-1 -1
10 9
2 3
1 2 3
4 5 6
-1 -2 -3
-4 -5 -6
0
输出样例:
1
5
#include<stdio.h>
int main()
{
int m,n;
while(scanf("%d",&m)!=EOF && m)
{
scanf("%d",&n);
int a[m][n],b[m][n];
int i,j,res=0,flag=0;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
for(i=0;i<m;i++)
{
flag=0;
for(j=0;j<n;j++)
{
scanf("%d",&b[i][j]);
b[i][j]+=a[i][j];
if (b[i][j])
flag = 1;
}
if(!flag)
res++;
}
for(j = 0;j<n;j++)
{
flag = 0;
for(i=0;i<m;i++)
if(b[i][j])
flag=1;
if(!flag)
res++;
}
printf("%d\n",res);
}
return 0;
}
5. xxx定律
对于一个数n,如果是偶数,就把n砍掉一半;如果是奇数,把n变成 3*n+ 1后砍掉一半,直到该数变为1为止。 请计算需要经过几步才能将n变到1,具体可见样例。
输入描述:
测试包含多个用例,每个用例包含一个整数n,当n为0 时表示输入结束。(1<=n<=10000)
输出描述:
对于每组测试用例请输出一个数,表示需要经过的步数,每组输出占一行。
输入样例#:
3
1
0
输出样例:
5
0
#include<stdio.h>
int main()
{
int n,cnt;
while(scanf("%d",&n)!=EOF && n){
cnt=0;
while(n>1){
if(n&1)
n=(3*n+1)/2;
else
n/=2;
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
5.2 继续xx定律
当n为3时,我们在验证xxx定律的过程中会得到一个序列,3,5,8,4,2,1,将3称为关键数,5,8,4,2称为覆盖数。现在输入n个数字a[i],根据关键数与覆盖数的理论,我们只需要验证其中部分数就可以确定所有数满足xxx定律,输出输入的n个数中的关键数。如果其中有多个关键数的话按照其输入顺序的逆序输出。
输入输出格式
输入描述:
输入数据包含多个用例,每个用例首先包含一个整数n,然后接下来一行有n个整数a[i],其中: 1<=n<=500, 1<a[i]<=1000
输出描述:
请计算并输出数组a中包含的关键数,并按照其输入顺序的逆序输出,每个用例输出占一行。
输入输出样例
输入样例#:
复制
3
3 8 4
5
3 8 4 7 15
5
3 8 4 15 7
0
输出样例#:
复制
3
15 7 3
7 15 3
题解
该题基于XX定律,就是说把该序列的数字都做一遍得到xx定律的序列合并为大集合,如果原输入序列的值不在这个大集合中,说明是关键字。
#include<bits/stdc++.h>
#include<string>
using namespace std;
set<int> myset;
int main()
{
int n;
vector<int> myv;
while(scanf("%d",&n)!=EOF && n)
{
myv.clear();
myset.clear();
int m;
for(int i = 0;i<n;i++)
{
scanf("%d",&m);
myv.push_back(m);
while(m!=1)
{
if(m%2)
m = 3*m+1;
else
m = m/2;
myset.insert(m);
}
}
for(int i =myv.size()-1;i>=0;i--)
{
if(myset.count(myv[i])==0)
cout<<myv[i]<<" ";
}
cout<<endl;
}
return 0;
}
#6 .欧拉回路
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
输入描述:
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结束。
输出描述:
每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
输入样例:
3 3
1 2
1 3
2 3
3 2
1 2
2 3
0
输出样例:
1
0
判断无向图是否存在欧拉回路:
- 所有点出度数==入度数
- 用bfs遍历看是否都能连通
#include<bits/stdc++.h>
using namespace std;
//namespace 标识符的各种可见范围,c++标准程序库中所有的标志符都被定义在一个std的命名空间
const int maxn = 1005;
int visit[maxn],d[maxn][maxn],degree[maxn];
int n,m;
void dfs(int s)
{
visit[s] = 1;
for(int i = 1;i<=n;i++)
{
if(d[s][i]&&!visit[i])
dfs(i);
}
}
int main(){
while(cin>>n && n){
memset(visit,0,sizeof(visit));
memset(d,0,sizeof(d));
memset(degree,0,sizeof(degree));
cin>>m;
int a,b;
for(int i =0;i<m;i++){
cin>>a>>b;
d[a][b] = d[b][a] = 1;
degree[a]++;
degree[b]++;
}
dfs(1);
bool flag = true;
for(int i =1;i<=n;i++){
if(!visit[i] || degree[i]%2){
cout<<0<<endl;
flag=false;
break;
}
}
if(flag)
cout<<1<<endl;
}
return 0;
}
7 .奥运排序问题
输入描述:
有多组数据。
第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。
第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。
接下来一行给出M个国家号。
输出描述:
排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例
对每个国家给出最佳排名排名方式 和 最终排名
格式为: 排名:排名方式
如果有相同的最终排名,则输出排名方式最小的那种排名,对于排名方式,金牌总数 < 奖牌总数 < 金牌人口比例 < 奖牌人口比例
如果有并列排名的情况,即如果出现金牌总数为 100,90,90,80.则排名为1,2,2,4.
每组数据后加一个空行。
输入样例
4 4
4 8 1
6 6 2
4 8 2
2 12 4
0 1 2 3
4 2
8 10 1
8 11 2
8 12 3
8 13 4
0 3
输出样例
1:3
1:1
2:1
1:2
1:1
1:1
#include<bits/stdc++.h>
using namespace std;
struct node{
int num; //国家号
double orderVlaue[4];// 不同排名方式的取值
int order[4]; //不同方式的排名
};
bool cmp0(node a, node b)// 按国家号排名
{
return a.num<b.num;
}
bool cmp1(node a,node b) //按金牌数排名,降序
{
return a.orderVlaue[0]>b.orderVlaue[0];
}
bool cmp2(node a,node b) //按奖牌数排名,降序
{
return a.orderVlaue[1]>b.orderVlaue[1];
}
bool cmp3(node a,node b) //按人均金牌数数排名,降序
{
return a.orderVlaue[2]>b.orderVlaue[2];
}
bool cmp4(node a,node b) //按人均奖牌数排名,降序
{
return a.orderVlaue[3]>b.orderVlaue[3];
}
int main()
{
int n,m,i,a,j;
while(scanf("%d %d",&n,&m)!=EOF){
node allNation[n],orderNation[m];
for(i = 0;i<n;i++)
{
cin>>allNation[i].orderVlaue[0]>>allNation[i].orderVlaue[1]>>a;
allNation[i].orderVlaue[2] = allNation[i].orderVlaue[0]/a;
allNation[i].orderVlaue[3] = allNation[i].orderVlaue[1]/a;
allNation[i].num = i;
}
for(i = 0;i<m;i++)
{
cin>>a;
orderNation[i] =allNation[a];
}
sort(orderNation,orderNation+m,cmp1); //按照金牌数排名
orderNation[0].order[0] = 1;
for(i = 1;i<m;i++)
{
if(orderNation[i].orderVlaue[0]==orderNation[i-1].orderVlaue[0])
orderNation[i].order[0] = orderNation[i-1].order[0];
else
orderNation[i].order[0] = i+1;
}
sort(orderNation,orderNation+m,cmp2); //按奖牌数排名
orderNation[0].order[1] = 1;
for(i = 1;i<m;i++)
{
if(orderNation[i].orderVlaue[1]==orderNation[i-1].orderVlaue[1])
orderNation[i].order[1] = orderNation[i-1].order[1];
else
orderNation[i].order[1] = i+1;
}
sort(orderNation,orderNation+m,cmp3); //按人均金牌数排名
orderNation[0].order[2] = 1;
for(i = 1;i<m;i++)
{
if(orderNation[i].orderVlaue[2]==orderNation[i-1].orderVlaue[2])
orderNation[i].order[2] = orderNation[i-1].order[2];
else
orderNation[i].order[2] = i+1;
}
sort(orderNation,orderNation+m,cmp4); //按人均奖牌数排名
orderNation[0].order[3] = 1;
for(i = 1;i<m;i++)
{
if(orderNation[i].orderVlaue[3]==orderNation[i-1].orderVlaue[3])
orderNation[i].order[3] = orderNation[i-1].order[3];
else
orderNation[i].order[3] = i+1;
}
sort(orderNation,orderNation+m,cmp0);
// for(i = 0;i<m;i++)
// {
// cout<<orderNation[i].num<<"[";
// for(j = 0;j<4;j++)
// {
// cout<<j+1<<":"<<orderNation[i].order[j]<<"||";
// }
// cout<<"]"<<endl;
//
// }
for(i = 0;i<m;i++)
{
int index = 0;
for(j = 1;j<4;j++)
{
if(orderNation[i].order[j]<orderNation[i].order[index])
index = j;
}
cout<<orderNation[i].order[index]<<":"<<index+1<<endl;
}
cout<<endl;
}
return 0;
}
8. 畅通工程(最小生成树-kruskal)
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
##输入输出格式
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M (N, M < =100 );随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
##输入输出样例
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
3
?
题解
#include<bits/stdc++.h>
using namespace std;
const int MAX = 105;
int n,m;
int node[MAX];
int sum,total;// sum表示总路程,total表示边的条数,最小生成树边有n-1条(n个节点)
struct edge{
int v1,v2;
int w;
};
edge ed[MAX];
//升序
bool cmp(edge a,edge b)
{
return a.w<b.w;
}
// node[i] = j 表示到i最近的点为j
//找到x的祖先
int findd(int x){
if(x==node[x])
return x;
node[x] = findd(node[x]);
return node[x];
}
int main()
{
while(scanf("%d",&n)!=EOF){
if(n==0) break;
scanf("%d",&m);
// 村庄的编号从1开始
for(int i = 1 ;i<=n;i++)
{
scanf("%d %d %d",&ed[i].v1,&ed[i].v2,&ed[i].w);
}
for(int i =1;i<=m;i++)
node[i] = i;
sort(ed+1,ed+n+1,cmp);
sum = 0;
total = 0;
for(int i = 1;i<=n;i++){
int fx = findd(ed[i].v1);
int fy = findd(ed[i].v2);
if(fx!= fy)
{
// printf("%d\n",i);
node[fx] = fy;
sum+=ed[i].w;
total++;
}
}
//printf("%d\n",total);
if(total<(m-1))
printf("?\n");
else
printf("%d\n",sum);
}
}
9. 畅通工程2(并查集,判断连通图)
##题目描述
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?
##输入输出格式
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
对每个测试用例,在1行里输出最少还需要建设的道路数目。
输入输出样例
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
##输出样例:
1
0
2
998
#include<bits/stdc++.h>
#define N 1000
using namespace std;
int d[N];
//找到x的祖先
int findn(int x)
{
if(x==d[x])
return d[x];
d[x] = findn(d[x]);
return d[x];
}
int main()
{
int n,m;
int city1,city2;
int fx,fy;
int sum;
while(scanf("%d",&n)!=EOF && n){
cin>>m;
for(int i = 0;i<N;i++)
d[i] = i;
sum=0;
for(int i =0;i<m;i++)
{
cin>>city1>>city2;
fx = findn(city1);
fy = findn(city2);
if(fx!=fy)
{
d[fx] = fy;
sum++;
}
}
// cout<<sum<<endl;
cout<<n-1-sum<<endl;
}
return 0;
}
10 .继续畅通工程(不完全最小生成树)
题目描述
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
输入输出格式
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。
当N为0时输入结束。
每个测试用例的输出占一行,输出全省畅通需要的最低成本。
输入输出样例
3
1 2 1 0
1 3 2 0
2 3 4 0
3
1 2 1 0
1 3 2 0
2 3 4 1
3
1 2 1 0
1 3 2 1
2 3 4 1
0
3
1
0
题解
#include<bits/stdc++.h>
using namespace std;
const int MAX = 105;
int n;
int node[MAX];
int sum=0,total=0;// sum表示总路程,total表示边的条数,最小生成树边有n-1条(n个节点)
struct edge{
int v1,v2;
int w;
int status;
};
edge ed[MAX];
//升序
bool cmp(edge a,edge b)
{
return a.w<b.w;
}
// node[i] = j 表示到i最近的点为j
//
int findd(int x){
if(x==node[x])
return x;
node[x] = findd(node[x]);
return node[x];
}
void mergeV(int x, int y,int w, int status)
{
int fx = findd(x);
int fy = findd(y);
if(fx!=fy)
{
node[fx] = fy;
total++;
if(status==0)
{
sum+=w;
}
}
return;
}
int main()
{
while(scanf("%d",&n)!=EOF && n){
sum = total = 0;
for(int i =1;i<=n;i++)
node[i] = i;
// 村庄的编号从1开始
for(int i = 1 ;i<=n*(n-1)/2;i++)
{
scanf("%d %d %d %d",&ed[i].v1,&ed[i].v2,&ed[i].w,&ed[i].status);
if(ed[i].status==1)
mergeV(ed[i].v1,ed[i].v2,ed[i].w,ed[i].status);
}
if(total==(n-1))
{
printf("0\n");
continue;
}
sort(ed+1,ed+n*(n-1)/2+1,cmp);
for(int i = 1;i<=n;i++){
if(ed[i].status==0)
{
mergeV(ed[i].v1,ed[i].v2,ed[i].w,ed[i].status);
ed[i].status = 1;
}
}
if(total>=(n-1))
printf("%d\n",sum);
}
}
11. Grading(简单模拟)
题目描述
Grading hundreds of thousands of Graduate Entrance Exams is a hard work. It is even harder to design a process to make the results as fair as possible. One way is to assign each exam problem to 3 independent experts. If they do not agree to each other, a judge is invited to make the final decision. Now you are asked to write a program to help this process. For each problem, there is a full-mark P and a tolerance T(<P) given. The grading rules are: • A problem will first be assigned to 2 experts, to obtain G1 and G2. If the difference is within the tolerance, that is, if |G1 - G2| ≤ T, this problem’s grade will be the average of G1 and G2. • If the difference exceeds T, the 3rd expert will give G3. • If G3 is within the tolerance with either G1 or G2, but NOT both, then this problem’s grade will be the average of G3 and the closest grade. • If G3 is within the tolerance with both G1 and G2, then this problem’s grade will be the maximum of the three grades. • If G3 is within the tolerance with neither G1 nor G2, a judge will give the final grade GJ.
输入输出格式
Each input file may contain more than one test case.
Each case occupies a line containing six positive integers: P, T, G1, G2, G3, and GJ, as described in the problem. It is guaranteed that all the grades are valid, that is, in the interval [0, P].
For each test case you should output the final grade of the problem in a line. The answer must be accurate to 1 decimal place.
##输入输出样例
20 2 15 13 10 18
14.0
##题目翻译
若|G1-G2|<=T re = (G1+G2)/2
若|G1-G2|>T then G3
if |G3-G1|<=T
if |G3-G2|<=T re = max(G1,G2,G3)
else re = (G3+G1)/2
else|G3-G1|>T
if |G3-G2|<=T re = (G3+G2)/2
else re = GJ
题解
using namespace std;
int main()
{
float p,t,g1,g2,g3,gj,re;
while(scanf("%f %f %f %f %f %f",&p,&t,&g1,&g2,&g3,&gj)!=EOF){
if(abs(g1-g2)<=t)
{
re = (g1+g2)/2;
}
else
{
if(abs(g3-g1)<=t)
{
if(abs(g3-g2)<=t)
re = max(g1,max(g2,g3));
else
re = (g3+g1)/2;
}
else
{
if(abs(g3-g2)<=t)
re = (g3+g2)/2;
else
re = gj;
}
}
printf("%.1f\n",re);
}
return 0;
}
#12. Sharing(简单模拟,map,vector)
##题目描述
To store English words, one method is to use linked lists and store a word letter by letter. To save some space, we may let the words share the same sublist if they share the same suffix. For example, “loading” and “being” are stored as showed in Figure 1.
Figure 1
You are supposed to find the starting position of the common suffix (e.g. the position of “i” in Figure 1).
##输入输出格式
For each case, the first line contains two addresses of nodes and a positive N (<= 10^5), where the two addresses are the addresses of the first nodes of the two words, and N is the total number of nodes. The address of a node is a 5-digit positive integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address is the position of the node, Data is the letter contained by this node which is an English letter chosen from {a-z, A-Z}, and Next is the position of the next node.
For each case, simply output the 5-digit starting position of the common suffix. If the two words have no common suffix, output "-1" instead.
输入输出样例
11111 22222 9
67890 i 00002
00010 a 12345
00003 g -1
12345 D 67890
00002 n 00003
22222 B 23456
11111 L 00001
23456 e 67890
00001 o 00010
00001 00002 4
00001 a 10001
10001 s -1
00002 a 10002
10002 t -1
67890
-1
题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
int s_address1,s_address2,n;
while(scanf("%d %d %d",&s_address1,&s_address2,&n)!=EOF){
map<int,int> mymap;
vector<int> word1;
vector<int> word2;
char letter;
int start,next;
for(int i = 0;i<n;i++)
{
scanf("%d %c %d",&start,&letter,&next);
mymap[start] = next;
}
while(s_address1!=-1)
{
word1.push_back(s_address1);
s_address1 = mymap[s_address1];
}
while(s_address2!=-1)
{
word2.push_back(s_address2);
s_address2 = mymap[s_address2];
}
int flag = 1;
for(int i =0;i<word1.size();i++)
{
for(int j = 0;j<word2.size();j++)
{
if(word1[i]==word2[j])
{
flag = 0;
printf("%05d\n",word2[j]);
break;
}
}
if(!flag)
break;
}
if(flag)
printf("-1\n");
}
return 0;
}
13. 找出直系亲属(并查集,简单模拟)
题目描述
如果A,B是C的父母亲,则A,B是C的parent,C是A,B的child,如果A,B是C的(外)祖父,祖母,则A,B是C的grandparent,C是A,B的grandchild,如果A,B是C的(外)曾祖父,曾祖母,则A,B是C的great-grandparent,C是A,B的great-grandchild,之后再多一辈,则在关系上加一个great-。
输入输出格式
输入包含多组测试用例,每组用例首先包含2个整数n(0<=n<=26)和m(0<m<50), 分别表示有n个亲属关系和m个问题, 然后接下来是n行的形式如ABC的字符串,表示A的父母亲分别是B和C,如果A的父母亲信息不全,则用-代替,例如A-C,再然后是m行形式如FA的字符串,表示询问F和A的关系。
如果询问的2个人是直系亲属,请按题目描述输出2者的关系,如果没有直系关系,请输出-。
具体含义和输出格式参见样例.
##输入输出样例
3 2
ABC
CDE
EFG
FA
BE
great-grandparent
-
##题解
#include<bits/stdc++.h>
using namespace std;
const int N = 26;
map<char,char> child;
// 一代代判断p的子孙中是否有c
int ischild(char p,char c)
{
int countg = 1;// 记录迭代次数
while(p!=NULL)
{
if(child[p]==c) // 若b是a的孩子
return countg;
// 不是就往下找
p = child[p];
countg++;
}
return -1;
}
string outanswer(int re,int flag) //flag=1 长辈,flag=0晚辈
{
string res;
if(re==1)
if(flag)
res = "parent";
else
res = "child";
else
{
if(flag)
res = "grandparent";
else
res = "grandchild";
for(int i = 2;i<re;i++)
res="great-"+res;
}
res+="\n";
return res;
}
int main()
{
int n,m,re;
string s;
char c1,c2;
while(scanf("%d %d",&n,&m)!=EOF){
child.clear();
for(int i = 0;i<n;i++)
{
cin>>s;
for(int i =1;i<3;i++)
if(s[i]!='-')
child[s[i]] = s[0];
}
for(int i = 0;i<m;i++)
{
cin>>s;
c1 = s[0];
c2 = s[1];
re = -1;
re = ischild(c1,c2);
if(re!=-1) // c1是c2的长辈
{
cout<<outanswer(re,1);
}
else{
re = ischild(c2,c1);
if(re!=-1)
{
cout<<outanswer(re,0);
}
else
cout<<'-'<<endl;
}
}
}
return 0;
}
#14. 寻找大富翁(排序算法)
题目描述
浙江桐乡乌镇共有n个人,请找出该镇上的前m个大富翁.
输入输出格式
每个用例首先包含2个整数n(0<n<=100000)和m(0<m<=10),其中: n为镇上的人数,m为需要找出的大富翁数, 接下来一行输入镇上n个人的财富值.
请输出乌镇前m个大富翁的财产数,财产多的排前面,如果大富翁不足m个,则全部输出,每组输出占一行.
输入输出样例
3 1
2 5 -1
5 3
1 2 3 4 5
5
5 4 3
题解
#include<stdio.h>
void bubblesort(int a[],int n)
{
int flag;
for(int i = 0;i<n;i++)
{
flag = 0;
for(int j = n-1;j>i;j--){//将最大的数往前串
if(a[j-1]<a[j])
{
flag = 1;
int temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
if(flag==0)break;
}
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF){
int a[100000];
for(int i =0;i<n;i++)
scanf("%d",&a[i]);
bubblesort(a,n);
if(n<m)
m = n;
for(int i = 0;i<m;i++)
printf("%d ",a[i]);
printf("\n");
}
return 0;
}
// 内置排序函数
#include<bits/stdc++.h>
using namespace std;
const long N =100005;
long possession[N];
bool cpm(int a,int b)
{
return a>b;
}
int main()
{
long n;
int m;
while(scanf("%ld %d",&n,&m)!=EOF){
for(int i = 0;i<n;i++)
{
cin>>possession[i];
}
sort(possession,possession+n,cpm);
if (m>n)
m = n;
cout<<possession[0];
for(int i = 1;i<m;i++)
{
cout<<" "<<possession[i];
}
cout<<endl;
}
return 0;
}
#15. 二叉搜索树(树的建立)
##题目描述
判断两序列是否为同一二叉搜索树序列
##输入输出格式
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
如果序列相同则输出YES,否则输出NO
输入输出样例
2
567432
543267
576342
0
YES
NO
题解
要判断两棵树是否一样,要检测其前序和中序遍历结果是否都相同
#include<bits/stdc++.h>
#include<cstring>
using namespace std;
#define MAXN 30
typedef struct Tree{
int value;
struct Tree *l,*r;
}tree;
tree* root;
int Torder[MAXN],cnt = 0;
// 建立新的节点
tree* newnode(int val)
{
tree* u = (tree*) malloc(sizeof(tree));
if(u!=NULL)
{
u->value = val;
u->l = u->r = NULL;
}
return u;
}
// 往二叉排序树插入新的节点
tree* addnode(tree *node,int val)
{
if(node==NULL)
{
node =newnode(val);
}
else{
if(val>=node->value)
node->r = addnode(node->r,val);
else
node->l = addnode(node->l,val);
}
return node;
}
void Inorder(tree* root)
{
if(root!=NULL)
{
Inorder(root->l);
Torder[cnt++] = root->value;
Inorder(root->r);
}
}
void PreOrder(tree* root)
{
if(root!=NULL)
{
Torder[cnt++] = root->value;
PreOrder(root->l);
PreOrder(root->r);
}
}
int main(){
int n;
while(scanf("%d",&n)!=EOF && n)
{
root = NULL;
cnt = 0;
string s;
cin>>s;
int lengthP = s.length();
int INorderP[lengthP],PREorderP[lengthP];
for(int i = 0;i<lengthP;i++)
{
root = addnode(root,s[i]-'0');
}
memset(Torder,0,sizeof(Torder));
cnt = 0;
Inorder(root);
for(int i = 0;i<lengthP;i++)
{
INorderP[i] = Torder[i];
}
memset(Torder,0,sizeof(Torder));
cnt = 0;
PreOrder(root);
for(int i = 0;i<lengthP;i++)
{
PREorderP[i] = Torder[i];
}
while(n--)
{
s = "";
cin>>s;
root = NULL;
int lengthA = s.length();
for(int i = 0;i<lengthA;i++)
{
root = addnode(root,s[i]-'0');
}
int INorderA[lengthA],PREorderA[lengthA];
memset(Torder,0,sizeof(Torder));
cnt = 0;
Inorder(root);
for(int i = 0;i<lengthA;i++)
{
INorderA[i] = Torder[i];
}
memset(Torder,0,sizeof(Torder));
cnt = 0;
PreOrder(root);
for(int i = 0;i<lengthA;i++)
{
PREorderA[i] = Torder[i];
}
int flag =