签到 2016.6.17

来源:互联网 发布:汉诺塔问题 python 编辑:程序博客网 时间:2024/05/01 22:02

1、Google Code Jam Qualification Round 2016_B

Problem

The Infinite House of Pancakes has just introduced a new kind of pancake! It has a happy face made of chocolate chips on one side (the “happy side”), and nothing on the other side (the “blank side”).

You are the head waiter on duty, and the kitchen has just given you a stack of pancakes to serve to a customer. Like any good pancake server, you have X-ray pancake vision, and you can see whether each pancake in the stack has the happy side up or the blank side up. You think the customer will be happiest if every pancake is happy side up when you serve them.

You know the following maneuver: carefully lift up some number of pancakes (possibly all of them) from the top of the stack, flip that entire group over, and then put the group back down on top of any pancakes that you did not lift up. When flipping a group of pancakes, you flip the entire group in one motion; you do not individually flip each pancake. Formally: if we number the pancakes 1, 2, …, N from top to bottom, you choose the top i pancakes to flip. Then, after the flip, the stack is i, i-1, …, 2, 1, i+1, i+2, …, N. Pancakes 1, 2, …, i now have the opposite side up, whereas pancakes i+1, i+2, …, N have the same side up that they had up before.

For example, let’s denote the happy side as + and the blank side as -. Suppose that the stack, starting from the top, is –+-. One valid way to execute the maneuver would be to pick up the top three, flip the entire group, and put them back down on the remaining fourth pancake (which would stay where it is and remain unchanged). The new state of the stack would then be -++-. The other valid ways would be to pick up and flip the top one, the top two, or all four. It would not be valid to choose and flip the middle two or the bottom one, for example; you can only take some number off the top.

You will not serve the customer until every pancake is happy side up, but you don’t want the pancakes to get cold, so you have to act fast! What is the smallest number of times you will need to execute the maneuver to get all the pancakes happy side up, if you make optimal choices?
Input

The first line of the input gives the number of test cases, T. T test cases follow. Each consists of one line with a string S, each character of which is either + (which represents a pancake that is initially happy side up) or - (which represents a pancake that is initially blank side up). The string, when read left to right, represents the stack when viewed from top to bottom.
Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the minimum number of times you will need to execute the maneuver to get all the pancakes happy side up.
Limits

1 ≤ T ≤ 100.
Every character in S is either + or -.

Small dataset

1 ≤ length of S ≤ 10.

Large dataset

1 ≤ length of S ≤ 100.

Sample

Input

5

-
-+
+-
+++
–+-

Output

Case #1: 1
Case #2: 1
Case #3: 2
Case #4: 0
Case #5: 3

In Case #1, you only need to execute the maneuver once, flipping the first (and only) pancake.

In Case #2, you only need to execute the maneuver once, flipping only the first pancake.

In Case #3, you must execute the maneuver twice. One optimal solution is to flip only the first pancake, changing the stack to –, and then flip both pancakes, changing the stack to ++. Notice that you cannot just flip the bottom pancake individually to get a one-move solution; every time you execute the maneuver, you must select a stack starting from the top.

In Case #4, all of the pancakes are already happy side up, so there is no need to do anything.

In Case #5, one valid solution is to first flip the entire stack of pancakes to get +-++, then flip the top pancake to get –++, then finally flip the top two pancakes to get ++++.

题意:
a string S
each character of which is
either + (which represents a pancake that is initially happy side up)
or - (which represents a pancake that is initially blank side up)

假设pancakes从上到下的标号为1-n,每次可以把从1-i的pancake进行翻转

求the minimum number of times you will need to execute the maneuver to get all the pancakes happy side up.

解题思路:
从最后一个pancake依次向前进行判断
若为 - ,然后判断第一个是否为 -, 若不是,修改为 - ,++times
然后进行一次翻转,++times
这样就保证了从n-1的每个pancake都变为 +,且操作次数最少

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 100 + 5;char s[maxn];char t[maxn];int main(){//    freopen("in.txt", "r", stdin);//    freopen("B-small-attempt2.in", "r", stdin);//    freopen("out.out", "w", stdout);    int T;    cin>>T;    int Case = 0;    getchar();    while (T--) {        gets(s);        int len = strlen(s);        int Count = 0;        for (int i=len-1; i>=0; --i) {            if (s[i] == '-') {                if (s[0] == '+') {                    ++Count;                    int j = 1;                    while (s[j] == '+') {                        s[j] = '-';                        ++j;                    }                }                ++Count;                for (int j=0,k=i; j<=i; ++j,--k) {                    if (s[k] == '-') {                        t[j] = '+';                    } else {                        t[j] = '-';                    }                }                for (int j=0; j<=i; ++j) {                    s[j] = t[j];                }            }        }        ++Case;        printf("Case #%d: %d\n", Case, Count);    }    return 0;}

2、五位以内对称素数

Description

判断一个数是否为对称且不大于五位数的素数。

Input
输入数据含有不多于50个的正整数(0
Output
对于每个n,如果该数是不大于五位数的对称素数,则输出“Yes”,否则输出“No”。每个判断结果单独列一行。
Sample Input

11 101 272

Sample Output

YesYesNo
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;char s[1000];bool IsPrime(int n);int main(){//    freopen("in.txt", "r", stdin);    int n;    while (scanf("%d", &n) != EOF && n!=0) {        sprintf(s, "%d", n);        int len = strlen(s);        bool flag = true;        for (int i=0; i<len/2; ++i) {            if (s[i] != s[len-1-i]) {                flag = false;                break;            }        }        if (len <= 5 && IsPrime(n) && flag) {            printf("Yes\n");        } else {            printf("No\n");        }    }    return 0;}bool IsPrime(int n){    if (n < 2) {        return false;    } else {        for (int i=2; i*i<=n; ++i) {            if (n%i == 0) {                return false;            }        }    }    return true;}

3、郭姐散步

Description

The first lady of our lab is GuoJie, GuoJie likes walking very much.Today GuoJie walks from the original point (0, 0), everytime he(may be she?) can go up or left or right a step.But she can't go back the point where she have visited.For example, if he goes up a step, she will be at (1, 0) and she never comes back the point.Now, if she can walk n(n <= 1000000) steps, can you find how many ways she can walk? the result mod 1e9 + 7.

Input
There will be T (T <= 100) cases, each case will input a n.
Output
For each group of input integers you should output how many ways GuoJie can walk in one line, and with one line of output for each line in input.
Sample Input

12

Sample Output

7

题意:
每次只能向上、左、右走,走n步共有多少种走法
结果对 1e9 + 7 取模

解题思路:
每次向左或向右走以后,再走就有2种走法
向上走以后,再走就有3种走法

假设走n步的走法为num[n]
若n > 3,那么从 n-1 到 n 的两种走法与三种走法的和为num[n-1]
又因为三种走法的个数为num[n-2]

所以递推公式为
num[n] = num[n-2] * 3 + (num[n-1] - num[n-2]) * 2

#include <iostream>#include <cstdio>using namespace std;typedef long long LL;const int maxn = 1000000 + 5;const int mod = (1e9 + 7);LL num[maxn];void Init(void);int main(){//    freopen("in.txt", "r", stdin);    int T;    Init();    while (scanf("%d", &T) != EOF) {        int n;        while (T--) {            scanf("%d", &n);            printf("%d\n", num[n]);        }    }    return 0;}void Init(void){    num[0] = 0;    num[1] = 3;    num[2] = 7;    LL t1, t2;    for (int i=3; i<maxn; ++i) {        t1 = num[i-2];        t2 = num[i-1] - t1;        num[i] = (3*t1 + 2*t2);        while (num[i] > mod) {            num[i] -= mod;        }    }}

4、蓝桥杯2016省赛C语言B组1题

煤球数目

有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),
….
如果一共有100层,共有多少个煤球?

请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

答案:171700

#include <iostream>using namespace std;int main(){    int sum = 0;    int t = 0;    for (int i=1; i<=100; ++i) {        t += i;        sum += t;    }    cout<<sum<<endl;    return 0;}

5、蓝桥杯2016省赛C语言B组2题

生日蜡烛

某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。

现在算起来,他一共吹熄了236根蜡烛。

请问,他从多少岁开始过生日party的?

请填写他开始过生日party的年龄数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

答案:26

解题思路:
利用求1-n的和的公式n * (n+1) / 2
暴力搜索

#include <iostream>using namespace std;int main(){    int flag = 0;    for (int i=0; i<100; ++i) {        for (int j=i+1; j<100; ++j) {            if (j*j+j - (i*i+i) == 472) {                cout<<i+1<<" - "<<j<<endl;                flag = 1;                break;            }        }        if (flag) {            break;        }    }    return 0;}

6、CodeForces_678A Johny Likes Numbers

题意:
找到能被 k 整除且大于 n 的最小的数

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <cmath>#include <cctype>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;const int mod = 1e9 + 7;const int INF = 0x7fffffff;int main(){#ifdef __AiR_H    freopen("in.txt", "r", stdin);#endif // __AiR_H    int n, k;    scanf("%d%d", &n, &k);    int ans;    if (n > k) {        ans = (n/k + 1) * k;    } else if (n < k) {        ans = k;    } else {        ans = n * 2;    }    printf("%d\n", ans);    return 0;}

7、CodeForces_678B The Same Calendar

题意:
当前为年份为 y,找到与当前年份日历一样的下一年

解题思路:
闰年366天,非闰年365天
366%7 = 2,365%7 = 1
设置一个累加器t
因为所求年份与当前年份都是闰年年或都不是闰年
那么我们就可以从下一年开始, 每过一年,如果上一年是闰年,那么所有的这一年的每一天的星期数就是对应于上一年每一天的星期数+2,不是闰年就+1
只要t%7 == 0,且这一年和y一样是闰年或一样非闰年,那么这两年天数一样,每一天对应的星期数也一样,所以日历就是一样的

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <cmath>#include <cctype>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;const int mod = 1e9 + 7;const int INF = 0x7fffffff;bool IsLeap(int n);int main(){#ifdef __AiR_H    freopen("in.txt", "r", stdin);#endif // __AiR_H    int y;    scanf("%d", &y);    int t = 0;    int ans = y;    while (1) {        ++ans;        if (IsLeap(ans)) {            t += 2;        } else {            t += 1;        }        if (t % 7 == 0 && IsLeap(ans) == IsLeap(y)) {            break;        }    }    printf("%d\n", ans);    return 0;}bool IsLeap(int n){    if (n%400 == 0) {        return true;    }    if (n % 4 == 0 && n % 100 != 0) {        return true;    }    return false;}

8、 CodeForces_681B Economy Game

题意:
问是否有非负的整数 a,b,c 满足 a × 1 234 567 + b × 123 456 + c × 1 234 = n

解题思路:
只要枚举出其中两个,另一个用取模判断一下就好了
因为 a、b 的取值范围较小
a 枚举到 a * 1234567 <= n
b 枚举到 b * 123456 <= n - a * 1234567
然后判断 (n - a * 1234567 - b * 123456) 是否可以 mod 1234 就可以了

我:
被自己蠢哭,下面是我刚开始写的脑残代码,枚举了那么多,还得排序再二分找,费时费空间,不过 CF 的评测机也真是快,我的代码竟然 655 ms 过了
比赛的时候没有锁题,否则肯定有人来 Hack 窝,但是会失败…

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <cmath>#include <cctype>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;const int mod = 1e9 + 7;const int INF = 0x7fffffff;const int maxn = 7e6;int num[maxn];int Count = 0;int cmp_num(const void* a, const void* b);int main(){#ifdef __AiR_H    freopen("in.txt", "r", stdin);#endif // __AiR_H    for (int j = 0; j < 8102; ++j) {        for (int k = 0; k < 812; ++k) {            ull t = 123456 * j + 1234567 * k;            if (t > 1e9) {                break;            }            num[Count] = t;            ++Count;        }    }    qsort(num, Count, sizeof(num[0]), cmp_num);    int n;    while (scanf("%d", &n) != EOF) {        bool YES = false;        if (n%1234567 == 0) {            YES = true;        } else if (n%123456 == 0) {            YES = true;        } else if (n%1234 == 0) {            YES = true;        } else if (n > 123456) {            int t = lower_bound(num, num+Count, n) - num;            for (int i = t; i >= 0; --i) {                int x = n - num[i];                if (x >= 0 && x%1234 == 0) {                    YES = true;                    break;                }            }        }        if (YES) {            printf("YES\n");        } else {            printf("NO\n");        }    }    return 0;}int cmp_num(const void* a, const void* b){    return (*(int*)a - *(int*)b) > 0 ? 1 : -1;}
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <cmath>#include <cctype>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;const int mod = 1e9 + 7;const int INF = 0x7fffffff;const int x = 1234567, y = 123456, z = 1234;int main(){#ifdef __AiR_H    freopen("in.txt", "r", stdin);#endif // __AiR_H    int n;    scanf("%d", &n);    bool YES = false;    for (int i = 0; x * i <= n; ++i) {        for (int j = 0; y * j <= n - x*i; ++j) {            if ((n - x*i - y*j)%z == 0) {                YES = true;                break;            }        }        if (YES) {            break;        }    }    if (YES) {        printf("YES\n");    } else {        printf("NO\n");    }    return 0;}

9、CodeForces_682A Alyona and Numbers

题意:
给出 n,m
(x + y) mod 5 = 0,(1 ≤ x ≤ n, 1 ≤ y ≤ m)(1 ≤ n, m ≤ 1 000 000)求满足条件的 (x, y) 的对数

解题思路:
分别求出 m % 5 = 1、2、3、4、5 的个数
然后分别乘以 n %5 = 4、3、2、1、0 的个数再求和

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <cmath>#include <cctype>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;const ull mod = 1e9 + 7;const int INF = 0x7fffffff;int num[10];int main(){#ifdef __AiR_H    freopen("in.txt", "r", stdin);#endif // __AiR_H    int n, m;    scanf("%d%d", &n, &m);    memset(num, 0, sizeof(num));    ull sum = 0;    if (m >= 1) {        num[4] += 1;    }    if (m >= 2) {        num[3] += 1;    }    if (m >= 3) {        num[2] += 1;    }    if (m >= 4) {        num[1] += 1;    }    for (int i = m; i > m-5 && i != 0; --i) {        num[5 - i%5] += i/5;        sum += num[5 - i%5];    }    ull ans = n/5*sum;    for (int i = 1; i <= n%5; ++i) {        ans += num[i];    }    printf("%I64d", ans);    return 0;}

10、Codeforces_682B Alyona and Mex

题意:
给定序列经过变换(序列中的元素向下减)后,使序列中第一个未出现的整数最大

解题思路:
排序以后判断从 1 ~ n 最多能有多少个数

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <cmath>#include <cctype>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;const ull mod = 1e9 + 7;const int INF = 0x7fffffff;const int maxn = 1e6 + 10;int num[maxn];int main(){#ifdef __AiR_H    freopen("in.txt", "r", stdin);#endif // __AiR_H    int n;    scanf("%d", &n);    queue<int> Q;    for (int i = 1; i <= n; ++i) {        Q.push(i);    }    for (int i = 1; i <= n; ++i) {        scanf("%d", &num[i]);    }    sort(num+1, num+n+1);    for (int i = 1; i <= n; ++i) {        if (Q.front() <= num[i]) {            Q.pop();        }    }    if (Q.empty()) {        printf("%d\n", n+1);    } else {        printf("%d\n", Q.front());    }    return 0;}
1 0
原创粉丝点击