A + B
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 21551 Accepted Submission(s): 12895
Problem Description
读入两个小于100的正整数A和B,计算A+B.
需要注意的是:A和B的每一位数字由对应的英文单词给出.
需要注意的是:A和B的每一位数字由对应的英文单词给出.
Input
测试输入包含若干测试用例,每个测试用例占一行,格式为"A + B =",相邻两字符串有一个空格间隔.当A和B同时为0时输入结束,相应的结果不要输出.
Output
对每个测试用例输出1行,即A+B的值.
Sample Input
one + two = three four + five six = zero seven + eight nine = zero + zero =
Sample Output
把英语单词分别讨论处理,注意输入格式。
#include<bits/stdc++.h>
using namespace std;
const int maxn=30;
string ch;
char c1[maxn],c2[maxn],c3[maxn],c4[maxn];
int ok(char c1[])
{
int a=0;
if(c1[0]=='o')
a=1;
else if(c1[0]=='e')
a=8;
else if(c1[0]=='n')
a=9;
else if(c1[0]=='z')
a=0;
else if(c1[0]=='t')
{
if(c1[1]=='w')
a=2;
else
a=3;
}
else if(c1[0]=='f')
{
if(c1[1]=='o')
a=4;
else
a=5;
}
else if(c1[0]=='s')
{
if(c1[1]=='i')
a=6;
else
a=7;
}
return a;
}
int main()
{
while(true)
{
getline(cin,ch);//read
int len=ch.size();
int i=0;
int j1=0,j2=0,j3=0,j4=0;
int f1=0,f11=0,f21=0;
for(int i=0; i<len; i++)
{
//cout<<ch[i]<<endl;
if(ch[i]=='=')break;
if(ch[i]=='+')
{
f1=1;
++i;
continue;
}
if(ch[i]==' '&&!f1)
{
f11=1;
continue;
}
if(ch[i]==' '&&f1)
{
f21=1;
continue;
}
if(f1)//+后面
{
if(!f21)
{
c3[j3++]=ch[i];
}
else
{
c4[j4++]=ch[i];
}
}
else //+前面
{
if(!f11)
{
c1[j1++]=ch[i];
//cout<<c1[j1]<<endl;
}
else
{
c2[j2++]=ch[i];
}
}
}
int a=0,b=0,c=0,d=0;
int s1=0,s2=0;
if(j1&&j2)
{
a=ok(c1);
b=ok(c2);
s1=a*10+b;
}
else
{
a=ok(c1);
s1=a;
}
if(j3&&j4)
{
c=ok(c3);
d=ok(c4);
s2=c*10+d;
}
else
{
c=ok(c3);
s2=c;
}
if(a==0&&c==0)
return 0;
//cout<<s1<<" "<<s2<<endl;
cout<<s1+s2<<endl;
}
}
最大连续子序列
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 44756 Accepted Submission(s): 20452
Problem Description
给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ...,
Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,
例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和
为20。
在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该
子序列的第一个和最后一个元素。
Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,
例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和
为20。
在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该
子序列的第一个和最后一个元素。
Input
测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( < 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元
素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。
素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。
Sample Input
6 -2 11 -4 13 -5 -2 10 -10 1 2 3 4 -5 -23 3 7 -21 6 5 -8 3 2 5 0 1 10 3 -1 -5 -2 3 -1 0 -2 0
Sample Output
20 11 13 10 1 4 10 3 5 10 10 10 0 -1 -2 0 0 0
Total Submission(s): 85855 Accepted Submission(s): 45590
Hint
Hint
Huge input, scanf is recommended.
相当于一个简单的动态规划,当和s<0,更新s和左右端点为ai,当s>0时更新右端点为ai,当s>maxx时,更新左右答案。
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 10000 + 66;
int a[maxn];
int main()
{
int k;
while (scanf("%d",&k)&&k)
{
for (int i = 1; i <= k; i++)
{
scanf("%d", &a[i]);
}
int s = 0;
int maxx = -99999999;
int l1 = 0, l2 = 0;
int ansa = 0, ansb = 0;
for (int i = 1; i <= k; i++)
{
if (s < 0)
{
s = a[i];
l1 = a[i];
l2 = a[i];
}
else
{
s += a[i];
l2 = a[i];
}
if (s > maxx)
{
maxx = s;
ansa = l1;
ansb = l2;
}
}
if(maxx>=0)
printf("%d %d %d\n", maxx,ansa,ansb);
else
{
printf("%d %d %d\n", 0, a[1], a[k]);
}
}
//getchar();
return 0;
}
畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 85855 Accepted Submission(s): 45590
Problem Description
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?
Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最少还需要建设的道路数目。
Sample Input
4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0
Sample Output
1 0 2 998
Huge input, scanf is recommended.
Hint
Hint
Source
Recommend
JGShining
简单的并查集应用,利用并查集缩点之后,形成n个联通块,应该加上n-1条路。
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 10000 + 66;
int fa[maxn];
int find(int x)
{
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void init(int x, int y)
{
int fx = find(x);
int fy = find(y);
if (fx != fy)
{
fa[fx] = fy;
}
}
int main()
{
int n,m;
while (scanf("%d",&n)&&n)
{
for (int i = 1; i <= n; i++)fa[i] = i;
scanf("%d", &m);
while (m--)
{
int u, v;
scanf("%d %d", &u, &v);
init(u, v);
}
for (int i = 1; i <= n; i++)
{
find(i);
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (i == fa[i])ans++;
}
printf("%d\n", ans - 1);
}
}
开门人和关门人
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 22975 Accepted Submission(s): 11504
Problem Description
每天第一个到机房的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的机房签
到、签离记录,请根据记录找出当天开门和关门的人。
到、签离记录,请根据记录找出当天开门和关门的人。
Input
测试输入的第一行给出记录的总天数N ( > 0 )。下面列出了N天的记录。
每天的记录在第一行给出记录的条目数M ( > 0 ),下面是M行,每行的格式为
证件号码 签到时间 签离时间
其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。
每天的记录在第一行给出记录的条目数M ( > 0 ),下面是M行,每行的格式为
证件号码 签到时间 签离时间
其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。
Output
对每一天的记录输出1行,即当天开门和关门人的证件号码,中间用1空格分隔。
注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,
且没有多人同时签到或者签离的情况。
注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,
且没有多人同时签到或者签离的情况。
Sample Input
3 1 ME3021112225321 00:00:00 23:59:59 2 EE301218 08:05:35 20:56:35 MA301134 12:35:45 21:40:42 3 CS301111 15:30:28 17:00:10 SC3021234 08:00:00 11:25:25 CS301133 21:45:00 21:58:40
Sample Output
ME3021112225321 ME3021112225321 EE301218 MA301134 SC3021234 CS301133
考察结构体排序,注意读入,排两遍序之后输出即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
using namespace std;
const int maxn = 1000 + 66;
struct student
{
char name[20];
int h, m, s;
int h1, m1, s1;
} a[maxn];
bool cmp1(student a,student b)
{
if (a.h < b.h)
return true;
else if (a.h > b.h)
return false;
else
{
if (a.m < b.m)
return true;
else if (a.m > b.m)
return false;
else
{
if (a.s < b.s)
return true;
else if (a.s > b.s)
return false;
}
}
return true;
}
bool cmp2(student a, student b)
{
if (a.h1 < b.h1)
return true;
else if (a.h1 > b.h1)
return false;
else
{
if (a.m1 < b.m1)
return true;
else if (a.m1> b.m1)
return false;
else
{
if (a.s1 < b.s1)
return true;
else if (a.s1 > b.s1)
return false;
}
}
return true;
}
int main()
{
int t;
while (scanf("%d",&t)!=EOF)
{
while(t--)
{
int m;
scanf("%d", &m);
int m1=m;
int id = 0;
while (m1--)
{
scanf("%s", a[++id].name);
scanf("%d:%d:%d ", &a[id].h, &a[id].m, &a[id].s);
scanf("%d:%d:%d", &a[id].h1, &a[id].m1, &a[id].s1);
}
sort(a + 1, a+m + 1,cmp1);
cout << a[1].name << " ";
sort(a + 1, a + m + 1, cmp2);
cout << a[m].name << endl;
}
}
}
排名
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 32662 Accepted Submission(s): 11974
Problem Description
今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑
每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的
考生,并将他们的成绩按降序打印。
每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的
考生,并将他们的成绩按降序打印。
Input
测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N
< 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一
名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号
(题目号由1到M)。
当读入的考生人数为0时,输入结束,该场考试不予处理。
< 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一
名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号
(题目号由1到M)。
当读入的考生人数为0时,输入结束,该场考试不予处理。
Output
对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高
到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考
号的升序输出。
到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考
号的升序输出。
Sample Input
4 5 25 10 10 12 13 15 CS004 3 5 1 3 CS003 5 2 4 1 3 5 CS002 2 1 2 CS001 3 2 3 5 1 2 40 10 30 CS001 1 2 2 3 20 10 10 10 CS000000000000000001 0 CS000000000000000002 2 1 2 0
Sample Output
3 CS003 60 CS001 37 CS004 37 0 1 CS000000000000000002 20
考察结构体排序,排好序选择输出即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
const int maxn = 1000 + 66;
int grade[maxn];
struct student
{
char name[maxn];
int num;
int grades;
}a[maxn];
bool cmp1(const student a, const student b)
{
if (a.grades > b.grades)return true;
else if (a.grades < b.grades)return false;
else
{
return strcmp(a.name,b.name)<0;
}
return true;
}
int main()
{
int n, m, g;
while (scanf("%d %d %d", &n, &m, &g)&&n)
{
for (int i = 1; i <= m; i++)
{
scanf("%d", &grade[i]);
}
for (int i = 1; i <= n; i++)a[i].grades=0;
int ans = 0;
for (int i = 1; i <= n; i++)
{
scanf("%s %d", a[i].name, &a[i].num);
for (int j = 1; j <= a[i].num; j++)
{
int id;
scanf("%d", &id);
a[i].grades += grade[id];
}
if (a[i].grades >= g)
{
ans++;
}
}
printf("%d\n", ans);
//cout << n << endl;
sort(a + 1, a + n + 1, cmp1);
for (int i = 1; i <= n; i++)
{
if (a[i].grades >= g)printf("%s %d\n", a[i].name, a[i].grades);
}
}
return 0;
}