ZZU - 比赛(2015/4/12)

Problem B: 零比特填充-透明传输

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 93   Solved: 27
[ Submit][ Status][ Web Board]

Description

      在计算机网络中为了实现协议的透明传输,需要使用到一种差错检测的方法(零比特填充)。方法具体实现为:

       在发送端,先扫描整个信息字段,只要发现5个连续的1,则立即填入一个0,以保证不会出现6个连续的1。而计算机专业的小A看到密密麻麻的01比特流,心里当时就懵逼了。所以小A求助于ACM的众大神们帮他判断他得到的处理过的01串,如果小A得到正确的比特流,那么神奇的ACM小伙伴们帮他转换为未经零比特填充处理过的比特流,否则输出"Bad luck!".

Input

输入包括一个多组测试数据:

每组测试数据包括一个L(0<L<1000)和一个L长度的01串

(L为01串的长度,01串为小A得到的处理过的01串)

Output

如果小明得到正常传输的01串,则还原处理过的01串得到未处理过的01串,如果小明得到错误的01串则输出"Bad luck!"(不包括双引号)

Sample Input

11 01010101010
16 1111110000011110
10 1000111110

Sample Output

01010101010
Bad luck!
100011111

HINT

[ Submit][ Status][ Web Board]


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;
 
int L;
 
char str[1005];
 
int judge() {
    int cnt = 0;
    for(int i = 0; i < L; i++) {
        if(str[i] == '1') cnt ++;
        else cnt = 0;
        if(cnt >= 6) return 0;
    }
    return 1;
}
 
 
 
int main() {
    while(scanf("%d", &L) != EOF) {
        scanf("%s", str);
        if(judge()) {
            int cnt = 0;
            for(int i = 0; i < L; i++) {
                if(str[i] == '1') {
                    printf("%c", str[i]);
                    cnt ++;
                }
                else {
                    printf("%c", str[i]);
                    cnt = 0;
                }
                if(cnt >= 5) {
                    cnt = 0;
                    i ++;
                    continue;
                }
            }
            printf("\n");
        }
        else {
            printf("Bad luck!\n");
        }
    }
    return 0;
}





Problem C: 约瑟夫环

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 42   Solved: 18
[ Submit][ Status][ Web Board]

Description

在我们学习C语言的时候,都接触过约瑟夫环。首先,标号为1-n的n个人站成一圈。然后,重复数字1-m。说1或者说m的人
退出游戏。这个过程直到没人了才会结束。比如,当n=5,m=2的时候,假定说1的人退出游戏。那么我们得到顺序:1,3
5,4,2。现在,我们重新定义规则。大部分规则不会改变,仅仅改变谁退出游戏。规则为:说1的人离开和第一个离开的人代表
Monday(星期一),第二个离开的人代表Tuesday(星期二),。。。,第七个代表Sunday(星期日),第八个代表Monday(星期一),
等等。我们想知道的是最后一个离开的人代表什么。

Input

输入包含多组数据(不会超过40组)。
每一组仅仅包含一个整数N(1<=N<=10^9)。
在N为0的时候输入结束。

Output

输出相应代表的字符串。这些字符串应该是下列字符串中的一个:{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday",
"Sunday"}。

Sample Input

1
0

Sample Output

Monday

HINT

[ Submit][ Status][ Web Board]



AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;
 
char str[8][15] = {" ", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
 
 
int main() {
    int n;
    while(scanf("%d", &n), n) {
        printf("%s\n", str[(n - 1)% 7 + 1]);
    }
    return 0;
}




Problem D: QQ

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 44   Solved: 22
[ Submit][ Status][ Web Board]

Description

我们每个人都有QQ号。但是,每个QQ号的价值是不同的。现在,我们定义一个方法来比较两个QQ号价值的大小。
1)QQ号长度越短价值越大。
2)如果QQ号长度一样,那么我们应该比较这个QQ号的在线天数和QQ号码中的数字。在QQ号码中,对于每一个数字N,价值应该加上N;另外,如果一个数字N连续出现最多M(M>1)次,那么值应该额外加上(N+1)^(M+1)。对于在线天数,每在线一天会使该QQ号的价值加上1。

Input

输入包含多组测试数据。
每一个测试数据包含两行,第一行用两个字符串表示第一个QQ的信息:第一个字符串为长度为L(0<L<13)的QQ号,
第二个字符串为一个整数,表示在线天数D(0<D<=1000000)。第二行表示第二个QQ的
信息,格式和第一行一样。

Output

对于每一个测试数据,输出那个QQ的值大。
如果第一个QQ的值大,输出"First";如果第二个QQ值大,输出"Second",如果值相等,输出"Equal"。

Sample Input

12345 1
111111111111111 10000
12345 100
54321 100
1234222 100
1224222 100

Sample Output

First
Equal
Second

HINT

对于第三组测试数据, 第一个QQ值为: 1+2+3+4+2+2+2+3^4+100=197, 第二个QQ值为:1+2+2+4+2+2+2+3^3+3^4+100=223

[ Submit][ Status][ Web Board]


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define LL long long
#define INF 0x7fffffff
using namespace std;
 
char s1[20], s2[20];
int d1, d2;
int num1[10], num2[10];
 
int main() {
    while(scanf("%s %d", s1, &d1) != EOF) {
        scanf("%s %d", s2, &d2);
        int len1 = strlen(s1), len2 = strlen(s2);
        if(len1 < len2) {
            printf("First\n");
            continue;
        }
         
        if(len2 < len1) {
            printf("Second\n");
            continue;
        }
         
        LL v1 = d1, v2 = d2;
         
        memset(num1, 0, sizeof(num1));
        memset(num2, 0, sizeof(num2));
         
        for(int i = 0; i < len1; i++) {
            v1 += (s1[i] - '0');
            num1[s1[i] - '0'] ++;
        }
         
        for(int i = 0; i < len2; i++) {
            v2 += (s2[i] - '0');
            num2[s2[i] - '0'] ++;
        }
         
        for(int i = 1; i < 10; i++) {
            if(num1[i] > 1) v1 += pow(i + 1, num1[i] + 1);
            if(num2[i] > 1) v2 += pow(i + 1, num2[i] + 1);
        }
         
        if(v1 > v2) {
            printf("First\n");
        }
        else if(v1 == v2) {
            printf("Equal\n");
        }
        else {
            printf("Second\n");
        }
    }
    return 0;
}




Problem E: 行列式

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 40   Solved: 9
[ Submit][ Status][ Web Board]

Description

相信大家现在都已经学习过线性代数并能熟练掌握行列式的求法了吧,在这里我们定义一种运算方法为类行列式(其值对应于主对角线的乘积加权值减去副对角线的乘积加权,详见下方Hint)。出一道求解类行列式的简单题考验一下大家的基础数学以及代码能力

Input

首先输入一个正整数n(n<=11),接着输入n*n个小于等于11的整数;(不超过10个样例)

Output

在每行输出该n*n类行列式所对应的结果

Sample Input

3
1 2 3
4 5 6
7 8 9
2
1 2
3 4

Sample Output

0
-2

HINT

例如输入:

3

1 2 3

4 5 6

7 8 9

时,计算方法为:1*5*9+2*6*7+3*4*8-3*5*7-2*4*9-1*6*8 = 0

[ Submit][ Status][ Web Board]



想吐槽一下,一开始没特判1的情况,WA,以为想错啦,改用DFS,TLE,萎了好久。。。。


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;
 
int mp[35][35];
int n;
 
int main() {
    while(scanf("%d", &n) != EOF) {
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                scanf("%d", &mp[i][j]);
            }
        }
        
        if(n == 1) {
        	printf("%d", mp[0][0]);
        	continue;
        } 
        
        if(n == 2) {
            printf("%d\n", mp[0][0] * mp[1][1] - mp[0][1] * mp[1][0]);
            continue;
        }
         
        for(int j = n; j < n + n; j++) {
            for(int i = 0; i < n; i++) {
                mp[i][j] = mp[i][j - n];
            }
        }
        /*for(int i = 0; i < n + n; i++) {
            for(int j = 0; j < n + n; j++) {
                printf("%d ", mp[i][j]);
            }
            printf("\n");
        }*/
         
        LL ans = 0;
        for(int i = 0; i < n; i++) {
            LL tmp = 1;
            for(int j = 0; j < n; j++) {
                tmp *= mp[j][i+j]; 
            }
            ans += tmp;
        }
         
        for(int i = n; i < n + n; i++) {
            LL tmp = 1; 
            for(int j = 0; j < n; j++) {
                tmp *= mp[j][i-j]; 
            }
            ans -= tmp;
        }
         
        cout << ans << endl;
    }
    return 0;
}



Problem F: 简单求值

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 34   Solved: 4
[ Submit][ Status][ Web Board]

Description

最近小希同学学习了编程以后,觉得自己想做点什么东西出来,就想起老师之前提过的表达式求值问题。但是由于小希还是一个初学者,好多地方实现起来还很困难,于是他向你寻求帮助。为了简化问题,他只想写出能求表达式中只存在加,减,乘,除四种运算的表达式的值即可。怎么样,简单吧,快点动手解决它吧。

Input

输入有多组样例,每组只有一行字符串,字符串中没有空格,字符串的长度小于1000,且只含有数字和'+','-','*','/'(分别表示加减乘除四种运算,其中‘/’表示整除)。

Output

输出表达式的结果。结果确保在整数(int)范围内

Sample Input

1+2+3

Sample Output

6

HINT

[ Submit][ Status][ Web Board]


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <stack>
#define LL long long
#define INF 0x7fffffff
using namespace std;
 
char s[1005];
 
int mov;
int len;
 
int fun(int x) {
    int sum = 0;
    while(s[x] <= '9' && s[x] >= '0' && x < len) {
        sum = sum * 10 + s[x] - '0';
        mov ++;
        x ++;
    }
    return sum;
}
 
int main() {
    while(scanf("%s", s) != EOF) {
        len = strlen(s);
        stack<int> num;
        stack<char> cha;
        for(int i = 0; i < len; i++) {
            if(s[i] <= '9' && s[i] >= '0') {
                mov = 0;
                int t = fun(i);
                i += (mov-1);
                mov = 0;
                //printf("%d\n", t);
                num.push(t);
            }
            else if(s[i] == '+' || s[i] == '-') cha.push(s[i]);
            else if(s[i] == '*' || s[i] == '/') {
                int t1 = num.top();
                num.pop();
                mov = 0;
                int t2 = fun(i + 1);
                //printf("%d\n", t2);
                //int t3 = t1 * t2;
                if(s[i] == '*') num.push(t1 * t2);
                else num.push(t1 / t2);
                i += mov;
            } 
        }
         
        //printf("%d\n", num.size());
        //printf("%d\n", cha.size());
        int ans = 0;
        //num.pop();
         
        while(!cha.empty()) {
            int t = num.top();
            //printf("%d\n", t);
            num.pop();
            char ca = cha.top();
            cha.pop();
            if(ca == '+') {
                ans += t;
            }
            else {
                ans -= t;
            }
        }
        ans += num.top();
        printf("%d\n", ans);
    }
    return 0;
}



Problem G: C(C++)编译器

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 111   Solved: 30
[ Submit][ Status][ Web Board]

Description

在运行C(C++)代码之前,我们必须首先编译这些代码。只有代码被成功编译,我们才可以运行代码。现在你的任务是帮助
编译器检查函数的返回类型是否是正确的。为了简化问题,在这里,我们认为当且仅当返回类型是以下列表之一的才是正确的。
给定的列表为:{"void", "byte", "char", "int", "long", "float", "double", "__int64"}。比如:"int"是正确的,
但是,"integer"是错误的。

Input

输入包括多组测试数据(不会超过20组)。
每组测试数据在一行内包含一个长度为L(3<=L<=16)的字符串,代表函数的返回类型。
输入为"end"表示输入的结束,它不应该被处理。

Output

如果返回类型是正确的,输出"Yes",否则输出"No"。如果字符串是"end",不应该有任何输出。

Sample Input

int
class
long
long long
end

Sample Output

Yes
No
Yes
No

HINT

[ Submit][ Status][ Web Board]


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;
 
char str[8][20] = {"void", "byte", "char", "int", "long", "float", "double", "__int64"};
 
char s[20];
 
int main() {
    while(gets(s), strcmp(s, "end")) {
        int flag = 0;
        for(int i = 0; i < 8; i++) {
            if(!strcmp(s, str[i])) {
                flag = 1;
                printf("Yes\n");
            }
        }
        if(flag == 0) printf("No\n");
    }
    return 0;
}




Problem H: 数字游戏

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 80   Solved: 12
[ Submit][ Status][ Web Board]

Description

两个好朋友小D跟小C在一块玩数字游戏,小D给了小C一个正整数,并且规定如果从左向右读(称之为正序数)和从右向左读(称之为倒序数)是一样的,他们就称这个数为回文数。
,如果这个数不是回文数,将该数与他的倒序数相加,若其和不是回文数,则重复上述步骤,一直到获得回文数为止。例如:68变成154(68+86),再变成605(154+451),最后变成1111(605+506),而1111是回文数。
对此,小C开始抱怨,因为,如果小D给小C的那个数无论怎么变换都不可能是回文数,难道小C就要一直死循环下去吗?

Input

每行输入一个数字,可以多组测试数据。PS:输入的数据保证中间结果小于2^31。

Output

对应每个输入,输出两行,一行是变换的次数,一行是变换的过程。

Sample Input

27228
37649

Sample Output

3
27228--->109500--->115401--->219912
2
37649--->132322--->355553

HINT

[ Submit][ Status][ Web Board]



AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;
 
int ans;
int a[1000005];
 
int judge(int x) {
    char tmp[105];
    int sum = 0;
    while(x) {
        tmp[sum++] = x % 10 + '0';
        x /= 10;
    }
     
    for(int i = 0; i <= sum / 2; i++) {
        if(tmp[i] != tmp[sum - i - 1]) return 0;
    }
    return 1;
}
 
void fun(int x) {
    if(judge(x)) {
        a[ans ++] = x;
        printf("%d\n", ans - 1);
        for(int i = 0; i < ans - 1; i++) {
            printf("%d--->", a[i]);
        }
        printf("%d\n", a[ans - 1]);
        return;
    }
    else {
        a[ans ++] = x;
        int t = 0, tt = x;
        while(tt) {
            t = t * 10 + (tt % 10);
            tt /= 10;
        }
        fun(x + t);
    }
}
 
int main() {
    int n;
    while(scanf("%d", &n) != EOF) {
        ans = 0;
        fun(n);
    }
    return 0;
}







你可能感兴趣的:(ACM)