jtahstu的博客

root@jtahstu.com   Github   英文博客  

最新碎语:以后没事写写小的知识点吧

您的位置:jtahstu的博客 >算法> “青软杯”安徽科技学院第六届程序设计大赛_专业组

“青软杯”安徽科技学院第六届程序设计大赛_专业组


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手势解锁


本文由csdn-jtahstu原创,转载请注明出处,欢迎志同道合的朋友一起交流学习。本人QQ:1373758426和csdn博客地址,链接:http://blog.csdn.net/jtahstu  

代码为本人AC代码,最后附上几道难题的参考代码

比赛题目地址:http://183.167.205.82:8081/JudgeOnline/showcontest?contest_id=1043


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




---

本文章采用 知识共享署名2.5中国大陆许可协议 进行许可,欢迎转载,演绎或用于商业目的。

---

二维码加载中...

扫一扫移动端访问O(∩_∩)O

发表评论

66 + 21 =
路人甲 表情
看不清楚?点图切换 Ctrl+Enter快速提交
正在加载中……