Contest - “青软杯”安徽科技学院第六届程序设计大赛_专业组
Start time: 2015-04-18 08:00:00.0 End time: 2015-04-18 12:00:00.0
Current System Time: 2015-04-21 00:07:42.57 Contest Status: Ended
关于举办“青软杯”安徽科技学院
第六届程序设计大赛通知
ACM 国际大学生程序设计竞赛 (International Collegiate Programming Contest)是由美国计算机协会(ACM)主办的一项旨在展示大学生创新能力、团队精神和在压力下编写程序、分析和解决问题能力的著名竞赛。2010年以来,我校参与了历届安徽省 ACM 程序设计竞赛,并取得了优异的成绩。为选拔校 ACM 参赛队员,将举办“网博杯” 安徽科技学院第五届计算机程序设计大赛,热忱欢迎广大程序设计爱好者踊跃参加。
主办方:安徽科技学院教务处、校团委、数理与信息工程学院
承办方:数理与信息工程学院计算机系
赞助方:合肥青软动力科技有限公司
一、 比赛时间:2015 年 4 月 18(周六)上午 8:00~12:00
二、比赛地点:计算机与网络实验中心(力行楼六楼)
三、参赛对象:12~14 级计算机、网络、信息、电子等相关专业在校学生
四、 报名方式(免费报名参赛):
报名地点:力行楼六楼计算机网络实验中心人工智能实验室
报名时间:2014 年 3 月 18 日至 3 月 22 日
五、比赛设奖:设一等奖8%、二等奖12%、三等奖15%。
六、竞赛相关:
竞赛语言:C/C++/JAVA 环境:DevCpp /CodeBlock /Eclipse
比赛试题:采用 ICPC 样式——赛题 6~8 道
注意事项:
1. 练习比赛网站(安科 OJ):http://183.167.205.82:8081/JudgeOnline/
2. 计算机系 ACM/ICPC 学生活动室位于力行楼六楼,欢迎交流。
比赛 QQ 群:129073626(安科第六届校ACM大赛),内有相关资料和教程。
相关竞赛辅导将随后展开,请关注通知。
教务处、校团委、数理与信息工程学院
2015 年 3 月 11 日
Problem Id | Title | |
![]() | 1287 Problem A | A?A+B' |
![]() | 1288 Problem B | 点名什么的最烦了 |
![]() | 1289 Problem C | 数圈圈 |
![]() | 1290 Problem D | 扫雷 |
1291 Problem E | E决战21点 | |
![]() | 1292 Problem F | F谁比较2 |
![]() | 1293 Problem G | Hack It |
1294 Problem H | H妙手回春 | |
![]() | 1295 Problem I | I微博@粉丝 |
![]() | 1296 Problem J | J手势解锁 |
代码为本人AC代码,最后附上几道难题的参考代码
![]() | 1287 Problem A | A?A+B' |
A:A+B'
Time Limit:1000MS Memory Limit:65536K
Total Submit:68 Accepted:45
Description
A+B'
Input
Input
0<=A,B<=1e9
Output
Output
输出答案
Sample Input
4 3
27 12
100 200
Sample Output
7
48
102
Hint
Hint
B'就是B反过来啦
Source
思路:把后一个数分解存数组,再累乘、相加
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
//Sample Input
//4 3
//27 12
//100 200
//Sample Output
//7
//48
//102
using namespace std;
long long f(long long n)
{
long long sum=0,a[10]= {0},i=0,m=n;
if(m<10)return m;
else
{
while(m)
{
a[i]=m%10;
i++;
m/=10;
}
for(int j=0; j<i; j++)
sum=sum*10+a[j];
return sum;
}
}
int main()
{
long long a,b;
while(cin>>a>>b)
{
long long sum=f(b);
cout<<a+sum<<endl;
}
return 0;
}
![]() | 1288 Problem B | 点名什么的最烦了 |
点名什么的最烦了
Time Limit:1000MS Memory Limit:65536K
Total Submit:37 Accepted:32
Description
Description
土豪S在上XX科技学院,在这里老师们最喜欢上课点名了,为什么呢?:P。又到了上课时间,这次土豪S跟女友去庆祝生日了。老师会按学生的编号从小到大点名,但是老师并不是全部点名,他只点到第一个没到的人就停止了,土豪S想知道他到底有没有被点到。
Input
Input
输入数据第一行2个整数是n,m,分别表示这门课的学生总数和今天这门课的学生到的人数。接下来一行有n个不同的数a[i](1<=i<=n),表示学生的编号。下面一行m个不同的数b[i](1<=i<=m),表示到课学生的编号。最后一行一个数k表示土豪S的编号.
1<=m<n<=10^5
1<=a[i], b[i],k<=10^9且b[i]构成的集合包含于a[i]构成的集合
k包含于数组a,不包含于数组b
(多组数据输入)
Output
Output
如果点到土豪S,请输出”YES”;否则输出”NO”
Sample Input
4 3
1 2 3 4
1 2 3
4
5 1
4 6 8 10 12
8
8
5 1
44 45 46 47 48
44
45
Sample Output
NO
YES
NO
Source
思路:判断后一个数组是否包含土豪的编号,遍历一遍即可,简单
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
int main()
{
int m,n;
while(cin>>n>>m)
{
int a[1000+5]={0},b[1000+5]={0},s;
for(int i=0;i<n;i++)
cin>>a[i];
for(int j=0;j<m;j++)
cin>>b[j];
cin>>s;
bool flag=true;
for(int k=0;k<m;k++)
if(s==b[k])
{
flag=false;
break;
}
if(flag)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
![]() | 1289 Problem C | 数圈圈 |
数圈圈
Time Limit:1000MS Memory Limit:65536K
Total Submit:61 Accepted:40
Description
幼儿园的小朋友对数字其实不是很感兴趣,他们更感兴趣的是形状,现在给你一个数字,小朋友都会数出其中一共有多少圆圈圈
Input
Input
一个数字n长度不超过19位
Output
Output:
输出其中的圈圈数总数
Sample Input
14589
20869
12357
Sample Output
3
5
0
Source
思路:简单,自己理解
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
int main()
{
string s;
while(cin>>s)
{
int sum=0;
for(int i=0;i<s.length();i++)
{
if(s[i]=='0')sum++;
if(s[i]=='6')sum++;
if(s[i]=='8')sum+=2;
if(s[i]=='9')sum++;
}
cout<<sum<<endl;
}
return 0;
}
![]() | 1290 Problem D | 扫雷 |
扫雷
Time Limit:1000MS Memory Limit:65536K
Total Submit:43 Accepted:20
Description
扫雷
扫雷是一个经典的游戏,在一个N*M区域中
输入一个N*M的雷区中的k个雷坐标,打印出所有雷区的分布
一个位置如果是雷则表示为*,否则应该是0~8,表示他周围八连通域中的地雷总数。
Input
输入:
雷区尺寸 3=<n m="" <="20"
地雷数目 k<=M*N
和他们的坐标xi,yi
Output
输出
雷区的分布
每组后空一行
Sample Input
3 3 1
1 1
4 4 2
1 2
2 3
Sample Output
111
1*1
111
0111
01*2
012*
0011
Source
思路:存雷,二维数组值置为-1,然后遍历二维数组,看周边有几个雷,++
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
int main()
{
int a[200][200],m=0,n=0,x=0;
while(cin>>m>>n>>x)
{
int q=0,w=0;
memset(a,0,sizeof(a));
for(int k=0; k<x; k++)
{
cin>>q>>w;
a[q][w]=-1;
}
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
if(a[i][j]!=-1)
{
if(a[i-1][j]<0)a[i][j]++;
if(a[i+1][j]<0)a[i][j]++;
if(a[i][j-1]<0)a[i][j]++;
if(a[i][j+1]<0)a[i][j]++;
if(a[i-1][j-1]<0)a[i][j]++;
if(a[i+1][j+1]<0)a[i][j]++;
if(a[i-1][j+1]<0)a[i][j]++;
if(a[i+1][j-1]<0)a[i][j]++;
}
}
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
if(a[i][j]<0)cout<<"*";
else cout<<a[i][j];
cout<<endl;
}
cout<<endl;
}
return 0;
}
1291 Problem E | E决战21点 |
E决战21点
Time Limit:1000MS Memory Limit:65536K
Total Submit:30 Accepted:8
Description
21点是一个非常有趣的游戏,游戏规则是两个人各自抽取若干张牌后
看谁点数更大(但不能超过21点,否则算0)如果两个点数相等,则庄家获胜
2 3 4 5 6 7 8 9点数都是各自的数码
10 J Q K 都是10点
A既可以当成11点,也可以当成1点。
Input
输入:
每组数据包括 n m表示庄家和闲家的牌总数
接下来两行分别表示庄家和闲家的牌
Output
输出:
输出比分以及庄家赢(HOST WIN)还是闲家赢(GUEST WIN)
Sample Input
Sample Input
2 3
A J
A A Q
2 6
Q J
A A A A 7 K
Sample Output
Sample Output
21 vs 12 HOST WIN
20 vs 21 GUEST WIN
Source
思路:比赛时仅一个AC,表示我就读了一遍题目,这题pass了,还没想这题咋解
#include <stdio.h>//参考代码
#include <stdlib.h>
int host, guest, n, m, t, ace;
char s[3];
void solve()
{
host = 0, ace = 0;
while (n-- && scanf("%s", s))
if (strstr("23456789", s))
{
sscanf(s, "%d", &t);
host += t;
}
else if (strstr("10JQK", s))
host += 10;
else if (strstr("A", s))
{
ace++;
}
host += ace % 10;
while (ace-- && host <= 11)
host += 10;
guest = 0;
ace = 0;
while (m-- && scanf("%s", s))
if (strstr("23456789", s))
{
sscanf(s, "%d", &t);
guest += t;
}
else if (strstr("10JQK", s))
guest += 10;
else if (strstr("A", s))
{
ace++;
}
guest += ace % 10;
while (ace-- && guest <= 11)
guest += 10;
if (guest > 21)
guest = 0;
if (host > 21)
host = 0;
printf("%d vs %d ", host, guest);
if (guest > host)
puts("GUEST WIN");
else
puts("HOST WIN");
}
int main()
{
// freopen("A.in", "r", stdin);
// freopen("A.out", "w", stdout);
while (~scanf("%d %d ", &n, &m))
solve();
return 0;
}
![]() | 1292 Problem F | F谁比较2 |
F谁比较2
Time Limit:1000MS Memory Limit:65536K
Total Submit:43 Accepted:33
Description
定义一个整数N中的2的指数为N二的级别,比如4=2^2则4的二度为2,6=2^1*a则6的二度为1
你的任务就是给出a,b中谁更2
Input
1=>a,b<=1e9
Output
a,b中谁更2
用 > < =表示
Sample Input
4 6
17 4
4 12
Sample Output
>
<
=
Source
思路:分解有多少个二
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
int jt(long long n)
{
int ans=0;
long long m=n;
if(m%2==1)return 0;
while(m%2==0)
{
ans++;
m/=2;
}
return ans;
}
int main()
{
long long a,b;
while(cin>>a>>b)
{
int x=jt(a),y=jt(b);
if(x>y)cout<<">"<<endl;
else if(x==y)cout<<"="<<endl;
else cout<<"<"<<endl;
}
return 0;
}
![]() | 1293 Problem G | Hack It |
Hack It
Time Limit:1000MS Memory Limit:65536K
Total Submit:20 Accepted:10
Description
已知一段明文是用替换加密生成的,对付这种加密的最有效的方法是统计出文章的26个字母的频率,进而确定字母频率顺序。你的任务就是写一个程序计算每一个密文中26个字母按降序。
Input
一段字符串(大小写字母组成)不含有空格,(多组输入)
Output
对于每一行按频率降序输出出现的字母,相同频率(不区分大小写aA表示a出现了2次)的按照字母表顺序输出。
Sample Input
abcdefgh
aaabbcccc
abcdefghijklmnABCDZZZ
Sample Output
abcdefgh
cab
zabcdefghijklmn
Source
思路:结构体排序,存结构体,然后写个排序规则即可,新手和一般水平的很难写出
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
struct str
{
char c;
int n;
}a[26];
int cmp(const void*x,const void*y)
{
str* ta=(str*)x;
str* tb=(str*)y;
if(ta->n==tb->n)
{
return ta->c-tb->c;
}
else return tb->n-ta->n;
}
int main()
{
string s;
while(cin>>s)
{
for(int i=0;i<26;i++)
{
a[i].n=0;
}
for(int i=0;i<s.length();i++)
{
s[i]=tolower(s[i]);
a[s[i]-'a'].n++;
a[s[i]-'a'].c=s[i];
}
qsort(a,26,sizeof(str),cmp);
for(int i=0;i<26;i++)
if(a[i].n!=0)
cout<<a[i].c;
cout<<endl;
}
return 0;
}
1294 Problem H | H妙手回春 |
H妙手回春
Time Limit:1000MS Memory Limit:65536K
Total Submit:30 Accepted:7
Description
已知一个数N中 增加的m个数码(1-9),然后删除掉k个数码目标是使得结果最大(如果出现前导0则自动删除)。请输出最大可能的数字(结果不超过64位整数)
Input
已知一个数N (不超过64位整数)
Output
增加的m个数码(1-9),然后删除掉k个数码目标是使得结果最大(如果出现前导0则自动删除)。请输出最大可能的数字(结果和操作都不超过64位整数)
Sample Input
2
1234567800 4 1
1234567800 1 5
Sample Output
9999234567800
967800
Source
思路:这题比赛时困扰很长时间,无论是字符串处理,还是暴力模拟,都没写出来,下面为参考代码。听杨英豪的思路,可以理解,只是代码还没去写,那个思路挺简单,删某个字段的最小值即可。
#include <stdio.h>
#include <stdlib.h>
#define i64 long long
i64 n;
int m, k, t;
char temp[100];
i64 getmax(i64 n)
{
sprintf(temp, "%I64d", n);
int len = strlen(temp);
int i, j;
i64 s = 0, max = 0;
for (i = 0; i < len; i++)
{
s = 0;
for (j = 0; j < len; j++)
if (j != i)
s = s * 10+temp[j] - '0';
if (s > max)
max = s;
}
return max;
}
void solve()
{
i64 s = 0;
while (m--)
s = s * 10+9;
sprintf(temp, "%I64d%I64d", s, n);
sscanf(temp, "%I64d", &n);
while (k--)
n = getmax(n);
printf("%I64d\n", n);
}
int main()
{
freopen("A.in", "r", stdin);
freopen("A.out", "w", stdout);
for (scanf("%d", &t); t-- && scanf("%I64d%d%d", &n, &m, &k); solve())
;
return 0;
}
![]() | 1295 Problem I | I微博@粉丝 |
I微博@粉丝
Time Limit:1000MS Memory Limit:65536K
Total Submit:35 Accepted:14
Description
自从有了空间微博,童鞋们总爱相互@来秀感情。假设A @ B表示 A 是B的粉丝
注意自己@自己是不计算在之列的
请计算出每一个人A对应的被关心的人数和关心的人数
Input
第一个是N表示有圈子里面共有N个人 随后是人名(用一个字母表示)
随后一个整数M表示M个相互的@
随后是X@Y的内容(共M条)
Output
按原来的顺序输出每一个人的@ 与被@的个数 注意自己@自己是不计算在之列的
Sample Input
3 A B C
4
A @ B
B @ C
A @ C
A @ A
3 A B C
4
A @ A
B @ B
C @ C
A @ A
Sample Output
A 0 2
B 1 1
C 2 0
A 0 0
B 0 0
C 0 0
Source
思路:结构体,读入数据存结构体,然后输出,需要基础的结构体知识
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
struct people
{
string s;
int guan;//guanzhu
int bei;//beiguanzhu
} a[1000];
int main()
{
int n;
while(cin>>n)
{
for(int i=0; i<1000; i++)
{
a[i].guan=0;
a[i].bei=0;
}
for(int i=0; i<n; i++)
cin>>a[i].s;
int m;
cin>>m;
string z,x,y;
for(int i=0; i<m; i++)
{
cin>>z>>x>>y;
if(z==y)continue;
else
{
for(int j=0; j<n; j++)
if(z==a[j].s)a[j].guan++;
for(int j=0; j<n; j++)
if(y==a[j].s)a[j].bei++;
}
}
for(int i=0; i<n; i++)
cout<<a[i].s<<" "<<a[i].bei<<" "<<a[i].guan<<endl;
cout<<endl;
}
return 0;
}
![]() | 1296 Problem J | J手势解锁 |
J手势解锁
Time Limit:1000MS Memory Limit:65536K
Total Submit:37 Accepted:28
Description
很多同学的手机都采用手势解锁,我们这里定义任何9个点坐标分别是(0,0)~(3,3)点
可以对应数字键盘上的1~9 我们给出手势序列,请输出对应的数字密码
Input
手势
每个手势用一个数字N表示组成手势的点
随后是N个点的数字键盘坐标
Output
密码(用1-9表示的数字序列)
Sample Input
思路:水题,自己理解
8
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
4
0 0
1 1
2 2
2 1
Sample Output
12345678
1598
Source
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
int s[10]= {0};
int a,b;
for(int i=0; i<n; i++)
{
cin>>a>>b;
if(a==0&&b==0)s[i]=1;
if(a==0&&b==1)s[i]=2;
if(a==0&&b==2)s[i]=3;
if(a==1&&b==0)s[i]=4;
if(a==1&&b==1)s[i]=5;
if(a==1&&b==2)s[i]=6;
if(a==2&&b==0)s[i]=7;
if(a==2&&b==1)s[i]=8;
if(a==2&&b==2)s[i]=9;
}
for(int i=0; i<n; i++)
cout<<s[i];
cout<<endl;
}
return 0;
}
最终排名:
这次校赛呢,第一次参加,中间的运气和霉运也是并存,比赛前两天刚看的结构体排序,理解透彻了,这次一下子用到了两道题,这是运气。扫雷没有换行,换来了两个WA,可恶的罚时,使之错过了一等奖,与第三名仅仅只差18分钟,而两个WR可是罚时40分钟啊,最后几分钟被反超一下子掉到了第四,这是霉运。
第四名,还可以,二等奖,有了参加省赛的资格,一个月后就要举行了,亚历山大。在学校我们可能学的稍微好点,出去竞争才会发现山外有山,人外有人,愿不放弃,一直努力下去,不虚度光阴。
by jtahstu on 2015/4/21 0:40