山东科技大学第二届ACM校赛解题报告

这次校赛的目的,是为了省赛测试各种程序是否有问题。


热身赛的逗比题有点打击我,感觉正式赛应该不会出这种问题。开始的时候直接上了A题,然后大概是第六,前面好多友情队,正式队排名第二。

然后读了读B题,稍微想了一下,感觉不好搞,就去读了一下C题,结果C题的正方形判断只判断了四个直角,没有判四条边长度相等,交了两次 都是WA,然后想了一下 直接复制了一下上面的代码 改了下AC了, 总排名大概是第4的位置,然后看到有人拿下了E题,就读了一下E,结果发现是水题,就秒了。看了看榜,H又有人干掉了,就一次A了H。

然后没有榜,读了K,A了K题。直接没停下来。看到会做直接AC,AC的时候 已经被别人拿了FB。读了读 I,判断IP,这个题不是做过么,直接一次写过了,原来做这个题的时候,题目写不明白,坑死我了,交了好多次,名次一直在4-8之间,就进过一次第4。看了看F,试了试跑了一下循环,过了F。

这时候还有俩小时,然后到了第四小时,封榜了,也没做出第8个,瑞神第一,我第二。

本来已经做不动了,看看哪个都不好办,愁死了,还有人在一直期待我打败瑞神,然后就一直干D题,抱着打出来就能冠军的想法,不小心推出了D,运气吧,然后A掉了。这时候还有10分钟,就不想写了,考虑到瑞神可能也8题,很是纠结,因为别人除非9题,要么不可能超过我。心里觉得10分钟不会出题了,可还是想了10分钟B题。当然还没下手就到点了。

最后没想到易神A了第八个,罚时比我多不少,导致在我后面,瑞神做的虽然快,但是没A出第8个,就这样混了第一,哦,这里不得不说,刚刚读了锟锟的解题报告,有些遗憾,

锟神受打击,状态不好就挂在了后面。


Problem A: 简单计算

 

 

Description

给出n个十进制的数,找出这n个数的二进制表示中1的个数最少的数。

 

Input

输入的第一行为一个正整数T(1≤T≤20),代表测试数据组数。
对于每组测试数据,输入的第一行为一个正整数n(1≤n≤100000),第二行为n个正整数A1、A2、…、An(1≤Ai≤10^9),每个数之间以空格分隔。

 

Output

每组数据输出一行,先输出数据组数,再输出二进制中含1最少的数,如果存在多个数符合条件,输出最小的那个。具体输出格式见样例输出。

 

Sample Input

2 5 3 2 4 5 6 4 3 4 2 5

Sample Output

Case 1: 2
Case 2: 2



#include <iostream>
#include <limits.h>
#include <bitset>

using namespace std;

int main()
{
    int T, kase(0);
    cin >> T;
    while(T--){
        int n; cin >> n;
        int min1 = INT_MAX, minn = INT_MAX;
        for(int i = 0; i < n; ++i){
            int x;
            cin >> x;
            bitset<100> bit(x);
            if(bit.count() < min1 || (bit.count() == min1 && x < minn)){
                min1 = bit.count();
                minn = x;
            }
        }
        cout<<"Case "<< ++kase <<": "<< minn<<endl;
    }
    return 0;
}

<center><h2>Problem C: 正方形</h2><span class="green">Time Limit: </span>3 Sec  <span class="green">Memory Limit: </span>128 MB

</center><h2>Description</h2><div class="content"><p>在二维坐标轴内给出四个点,这四个点能否构成一个正方形。</p><p></p></div><h2>Input</h2><div class="content"><p>第一行包括一个整数:T(1≤T≤30),表明有T组测试数据。
下面各行有8个整数:x1,y1,x2,y2,x3,y3,x4,y4(数据均在-1000,1000之间),以逆时针顺序给出四个点的坐标。</p><p></p></div><h2>Output</h2><div class="content"><p>对每个样例,如果是正方形,则单独在一行内输出YES,否则,输出NO。</p><p></p></div><h2>Sample Input</h2><div class="content"><span class="sampledata"></span><pre>2
0 0 1 0 1 1 0 1
-1 0 0 -2 1 0 2 0

Sample Output

YES
NO

HINT

Append Code

#include<iostream>
#define len(i) (p[(i+1)%4].x-p[i].x)*(p[(i+1)%4].x-p[i].x)+(p[(i+1)%4].y-p[i].y)*(p[(i+1)%4].y-p[i].y)
#define A(i)   (p[(i+1)%4].x-p[i].x)*(p[(i+2)%4].x-p[(i+1)%4].x)+(p[(i+1)%4].y-p[i].y)*(p[(i+2)%4].y-p[(i+1)%4].y)!=0
using namespace std;
typedef unsigned long long llu;
struct pp{
    int x,y;
};
int main(){
    int T,kase=0;
    cin>>T;
    while(T--){
        pp p[4];
        for(int i =0; i<4; i++) cin>>p[i].x>>p[i].y;
        bool failed(false);
        for(int i =0;i< 3; i++) if( len(i) !=len(i+1) ) failed=true;
        for(int i =0;i<=3; i++) if( A(i) ) failed=true;
        cout<<( failed? "NO":"YES")<<endl;
    }
    return 0;
}


<center><h2>Problem D: 切蛋糕</h2><span class="green">Time Limit: </span>3 Sec  <span class="green">Memory Limit: </span>128 MB

</center><h2>Description</h2><div class="content"><p>今年是ACM集训队成立五周年,这是一个值得祝福的事情。我们该送给ACM集训队一个怎样的礼物呢?对于目前的大家来说,最好的礼物当然是省赛中的好成绩,我不能参赛,就送给学校一个DOOM III球形大蛋糕吧,这可是名牌,估计要花掉我半年的银子呢。切蛋糕的人,当然非吴教主莫属。
等一等,吃蛋糕之前先考大家一个问题:如果吴教主在蛋糕上切了N刀(教主刀法极好,每一刀都是一个绝对的平面),最多可以把这个球形蛋糕切成几块呢?
做不出这个题目,没有蛋糕吃的!</p><p></p></div><h2>Input</h2><div class="content"><p>第一行输出一个T(T≤100),表示有T组。每组包含一个整数N(1≤N≤1000),表示切的刀数。</p><p></p></div><h2>Output</h2><div class="content"><p>对于每组输入数据,请输出对应的蛋糕块数,每个测试实例输出一行。</p><p></p></div><h2>Sample Input</h2><div class="content"><span class="sampledata"></span><pre>3
1
2
4

Sample Output

2
4
15

HINT

Append Code

推出递推公式
 
 就很简单了

<pre name="code" class="cpp">#include<iostream>
using namespace std;
int main(){
    int n,x;
    cin>>n;
    while(n--){
        cin>>x;
        cout<<(x*x*x+5*x+6)/6<<endl;
    }
    return 0;
}

Problem E: 画笑脸
Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 37  Solved: 20
[Submit][Status][Web Board]
Description
用C语言画些任意大小的笑脸来。画法见Sample。


Input
T组数据,每组数据只有一个数N(1≤T≤20,1≤N≤20),表示笑脸的边长大小。


Output
把笑脸画出来吧。
注意:不要任何多余的空格和空行,每两组数据间输出一个空行。


Sample Input
3
1
2
3

Sample Output
/\ /\
  _

 /\    /\
/  \  /  \

    __

  /\       /\
 /  \     /  \
/    \   /    \


      ___
HINT

Append Code

#include<iostream>
using namespace std;

void pri(int n){
    for(int i =0; i<n; i++) cout<<" ";
}
int main(){
    int T,n;
    cin>>T;
    while(T--){
        cin>>n;
        for(int i =1; i<=n; i++){
            pri(n-i);
            cout<<"/";
            pri(2*i-2);
            cout<<"\\";
            pri(n-i);
            pri(n);
            pri(n-i);
            cout<<"/";
            pri(2*i-2);
            cout<<"\\"<<endl;
        }
        for(int i =1;i<n;i++) cout<<endl;
        pri(2*n);
        for(int i =0;i<n;i++) cout<<"_";
        cout<<endl;
        if(T) cout<<endl;
    }
    return 0;
}

Problem F: 猜数字

Time Limit: 3 Sec   Memory Limit: 128 MB

Description

小X最近发明了一种新游戏,他找来一堆卡片,每张卡片上都写有一个四位数,然后由两个人来玩。玩家A每次从这堆卡片中选择一张,然后由玩家B告诉玩家A他猜的数字中有几个与卡片中的相同,有几个与卡片中的位置相同。

例如,玩家A抽到的卡片是1122。如果玩家A猜1234,因为1,2这两个数字同时存在于这两个数中,而且1在这两个数中的位置是相同的,所以玩家B会告诉玩家A猜对了2个数字,其中一个在正确的位置。如果玩家A猜1111,那么玩家B会告诉他猜对2个数字,有2个在正确的位置。

现在给你一段游戏过程,你的任务是根据这过程来判断能否确定卡片上的四位数是什么。

Input

输入数据有多组。每组的第一行为一个正整数N(1≤N≤100),表示共有N次游戏过程。在接下来的N行中,每行三个整数x, y, z。玩家A猜这个四位数为x,然后玩家B回答猜对了y个数字,其中z个在正确的位置上。当N=0时,输入数据结束。

Output

每组输入数据对应一行输出。如果根据这段对话能确定这个四位数,则输出”Yes”,若不能,则输出"Not sure"。

Sample Input

6
4815 2 1
5716 1 0
7842 1 0
4901 0 0
8585 3 3
8555 3 2
2
4815 0 0
2999 3 3
0

Sample Output

Yes
Not sure

HINT

Append Code


#include<iostream>
#include<cstring>

using namespace std;

struct pp{
    int num,a,b;
    int d[4];
    pp(){}
    pp(int c) :num(c),a(0),b(0){
        for(int j =0;j<4;j++){
            d[j]=c%10;
            c/=10;
        }
    }
}p[110];

int main(){
    int n;

    while(cin>>n,n){
        for(int i =0;i<n;i++) {
            cin>>p[i].num>>p[i].a>>p[i].b;
            int temp=p[i].num;
            for(int j =0;j<4;j++){
                p[i].d[j]=temp%10;
                temp/=10;
            }
        }

        int have(0);
        for(int i =1000;i<10000;i++){
            int can(1);
            for(int j=0;j<n;j++){
                pp u(i);
                int n_a(0),n_b(0);
                for(int k=0;k<4; k++) if(u.d[k] ==p[j].d[k]) u.b++;
                if(u.b!=p[j].b) {can=0; break; }

                for(int k=0;k<4; k++){
                         if(u.d[0]==p[j].d[k]) {u.a++; u.d[0]=-1;}
                    else if(u.d[1]==p[j].d[k]) {u.a++; u.d[1]=-1;}
                    else if(u.d[2]==p[j].d[k]) {u.a++; u.d[2]=-1;}
                    else if(u.d[3]==p[j].d[k]) {u.a++; u.d[3]=-1;}
                }
                if(u.a!=p[j].a) {can=0; break; }
            }
            if(can){ have++;}
            if(have>2) break;
        }

        if(have==1) cout<<"Yes"<<endl;
        else cout<<"Not sure"<<endl;
    }
    return 0;
}


 
 

Problem H: 原创字符串

Time Limit: 3 Sec   Memory Limit: 128 MB

Description

我们称一个字符串s为“原创”当且仅当s不是N个字符串中的任意一个字符串的子串(子串:串中任意个连续字符组成的子序列)。现在有N个只包含小写字母的字符串,你的任务是根据给出的N个字符串构造一个长度最小的“原创”字符串,如果存在多个长度最小的则输出字典序最小的那个。

Input

对于每组测试数据,输入的第一行为一个正整数n(1≤n≤30)代表给定字符串的大小,接下来N行每行一个非空只包含小写字母的字符串,每个字符串长度不超过20。
输入以一行0结束。

Output

输出符合要求的字符串,每组答案占一行。

Sample Input

5
threehorses
goodsubstrings
secret
primematrix
beautifulyear
4
aa
bdefghijklmn
opqrstuvwxyz
c
0

Sample Output

j
ab

HINT

Append Code


#include<iostream>
#include<string>

using namespace std;
int out=0;
string s[35];
int n;

bool find(string s1,string s2){
    for(int i=0;i<s1.size()-s2.size()+1;i++){
        bool ok=0;
        if(s1[i]==s2[0]){
            ok=1;
            for(int j=1;j<s2.size();j++)
            if(s1[i+j]!=s2[j]) {ok=0; break;}
            if(ok) return 1;
        }
    }
    return 0;
}

void dfs(int v,int dig,int lem,string ss){
    ss[dig]=v;
    if(dig==lem-1){
        int ok=1;
        for(int i=0;i<n;i++){
            if(find(s[i],ss)) {ok=0; break;}
        }
        if(ok) { cout<<ss<<endl; out=1;}
    }
    else{
        for(int i =97; i<=122;i++)
            if(out==0) dfs(i,1,lem,ss);
            else break;
    }
    return;
}

int main(){
    while(cin>>n,n){
        out=0;
        for(int i =0;i<n;i++) cin>>s[i];

        for(int lem=1;;lem++){
            string ss(lem,0);
            for(int j=97;j<=122; j++)
                if(out==0) dfs(j,0,lem,ss);
                else break;
            if(out) break;
        }
    }
    return 0;
}

Problem I: IP地址

Time Limit: 1 Sec   Memory Limit: 32 MB
Submit: 2458   Solved: 54

Description

IP是英文Internet Protocol的缩写,意思是“网络之间互连的协议”,也就是为计算机网络相互连接进行通信而设计的协议。在因特网中,它是能使连接到网上的所有计算机网络实现相互通信的一套规则,规定了计算机在因特网上进行通信时应当遵守的规则。任何厂家生产的计算机系统,只要遵守IP协议就可以与因特网互连互通。正是因为有了IP协议,因特网才得以迅速发展成为世界上最大的、开放的计算机通信网络。因此,IP协议也可以叫做“因特网协议”。

互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),缩写为IP地址(IP Address),在Internet上,一种给主机编址的方式。常见的IP地址,分为IPv4与IPv6两大类。

IP地址被用来给Internet上的电脑一个编号。大家日常见到的情况是每台联网的PC上都需要有IP地址,才能正常通信。我们可以把“个人电脑”比作“一台电话”,那么“IP地址”就相当于“电话号码”,而Internet中的路由器,就相当于电信局的“程控式交换机”。

IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。例:点分十进IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)。

现在,根据以下规则,编写程序来判断一个字符串是否是“点分十进制”表示的IP地址。

1 IP地址由四个整数跟三个'.'组成,就是“a.b.c.d”的形式。

2 a,b,c,d四个部分的数字位数都可以是1~3位,其整数值都在0~255之间。

3 不能有除了数字和'.'之外的字符出现。

Input

输入有多行,每行是一个字符串s,s不超过100个字符。到文件尾结束。

Output

对于每个输入,判断串s是否为合法的IP地址,如果正确输出YES,否则NO。

Sample Input

192.168.100.16

Sample Output

YES

HINT

Append Code

#include<stdio.h>
#include<string.h>
#define N 105
int main()
{
    char a[N];
    while(gets(a)!=NULL)
    {
        int i,k=-1,wrong=0,sum,u=0;
        int n=strlen(a);
        for(i=0;i<=n;i++)
        {
            if(a[i]==46||a[i]==0)
            {
                sum=0,u++;
                if(i-k>4)
                    wrong=1;
                else
                {
                    for(k++;k<i;k++)
                       sum=sum*10+a[k]-48;
                    if(sum>255)
                        wrong=1;
                }
                k=i;
            }
            else if(a[i]>57||a[i]<48)
                wrong=1;
            if(a[i]==46&&(i==0||a[i-1]==46))
                wrong=1;
            if(wrong)
                goto end;
        }
    end:
        if(wrong||u!=4)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}

Problem K: 藏头诗

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 39   Solved: 25
[ Submit][ Status][ Web Board]

Description

ACM集训队有个小伙暗恋同班的姑娘,但是苦于害羞腼腆不敢直抒胸臆。于是小伙打算写一首英文情诗给她。为了使这首情诗高端霸气上档次,小伙经过三天三夜的精心创作写了一首藏头的情诗。请问你能看出他想要表达的真正内容吗?

Input

输入有T组(T≤20)。
每组数据第一行先输入一个整数N(N<100),表示下面要输入N行。
接下来N行,每行输入一段英文(长度小于100,只含大小写英文字母和空格)。

Output

每组输出一行,为藏头诗要表达的真正内容。

Sample Input

1
8
I am a handsome man
lonely and long for you attention
of all the girls I met you gave me the deepest impression
Very lucky to know you
earn money to make you happy
you are the world
oh be ma side
u are the happiest person in the world

Sample Output

IloVeyou

HINT

Append Code

#include<iostream>
#include<vector>
#include<string>

using namespace std;

int main(){
    int T,kase=0;
    cin>>T;
    while(T--){
        int n;
        cin>>n;cin.get();
        vector<char> v;
        while(n--){
            string s;
            getline(cin,s);
            v.push_back(s[0]);
        }
        for(int i =0; i<v.size();i++) cout<<v[i];
        cout<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值