CF39 A【模拟】、B【water】、D【water】、E【记忆化搜索博弈】、F【water】、H【water】、J【暴力||字符串哈希】

A - C*++ Calculations CodeForces - 39A
C*++ language is quite similar to C++. The similarity manifests itself in the fact that the programs written in C*++ sometimes behave unpredictably and lead to absolutely unexpected effects. For example, let’s imagine an arithmetic expression in C*++ that looks like this (expression is the main term):

expression ::= summand | expression + summand | expression - summand
summand ::= increment | coefficient*increment
increment ::= a++ | ++a
coefficient ::= 0|1|2|…|1000
For example, “5*a++-3*++a+a++” is a valid expression in C*++.

Thus, we have a sum consisting of several summands divided by signs “+” or “-“. Every summand is an expression “a++” or “++a” multiplied by some integer coefficient. If the coefficient is omitted, it is suggested being equal to 1.

The calculation of such sum in C*++ goes the following way. First all the summands are calculated one after another, then they are summed by the usual arithmetic rules. If the summand contains “a++”, then during the calculation first the value of the “a” variable is multiplied by the coefficient, then value of “a” is increased by 1. If the summand contains “++a”, then the actions on it are performed in the reverse order: first “a” is increased by 1, then — multiplied by the coefficient.

The summands may be calculated in any order, that’s why sometimes the result of the calculation is completely unpredictable! Your task is to find its largest possible value.

Input
The first input line contains an integer a ( - 1000 ≤ a ≤ 1000) — the initial value of the variable “a”. The next line contains an expression in C*++ language of the described type. The number of the summands in the expression does not exceed 1000. It is guaranteed that the line describing the expression contains no spaces and tabulation.

Output
Output a single number — the maximal possible value of the expression.

Examples
Input
1
5*a++-3*++a+a++
Output
11
Input
3
a+++++a
Output
8
Note
Consider the second example. Initially a = 3. Suppose that at first the first summand is calculated, and then the second one is. The first summand gets equal to 3, and the value of a is increased by 1. At the calculation of the second summand a is increased once more (gets equal to 5). The value of the second summand is 5, and together they give 8. If we calculate the second summand first and the first summand later, then the both summands equals to 4, and the result is 8, too.
分析:上面有+-多钟操作和++a、a++等操作,给你一个字符串,求其数字的最大值。关于a的运算顺序可以控制。5*a++-3++a+a++,先计算3*++a 再计算a++再计算5*a可得到最大值。

#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string>
#include <algorithm>
using namespace std;
#define ll long long int
const int maxn = 1234 + 10;

int cnt=0;
int now = 1;

struct node 
{
    int xi;
    int flag;

    bool friend operator < (node a,node b){
        return a.xi<b.xi;
    }


}a[maxn];

void f(){
    int pre=-1;
    char c;
    int xi = 0;
    c=getchar();
        if(c=='a'){//a++
            xi=1;
            pre=1;
            c=getchar();
            c=getchar();
        }else if(c=='+'){//++a
            xi=1;
            pre=0;
            c=getchar();
            c=getchar();
        }else{
            xi=c-'0';
            while(c=getchar()){
                if(c>='0'&&c<='9')
                    xi=xi*10+c-'0';
                else{
                    break;
                }
            }
            c=getchar();
            if(c=='a'){//a++
                pre=1;
                c=getchar();
                c=getchar();
            }else if(c=='+'){//++a
                pre=0;
                c=getchar();
                c=getchar();
            }
        }
    if(now)
        a[++cnt].xi=xi;
    else
        a[++cnt].xi=-xi;
    a[cnt].flag=pre;

}



int main()
{
    int n;
    scanf("%d",&n);
    getchar();
    char c;
    while(1){
        f();
        if(c=getchar()){
            if(c=='\n'){
                break;
            }else if(c=='+'){
                now=1;
            }else{
                now=0;
            }
        }
    }

    sort(a+1,a+1+cnt);
    int ans=0;
    for(int i=1;i<=cnt;i++){
        if(a[i].flag==1){

            ans+=a[i].xi*n;

            n++;
        }else{
            n++;
            ans+=a[i].xi*n;
        }
    }
    printf("%d\n",ans);


    return 0;
}

B - Company Income Growth CodeForces - 39B
Petya works as a PR manager for a successful Berland company BerSoft. He needs to prepare a presentation on the company income growth since 2001 (the year of its founding) till now. Petya knows that in 2001 the company income amounted to a1 billion bourles, in 2002 — to a2 billion, …, and in the current (2000 + n)-th year — an billion bourles. On the base of the information Petya decided to show in his presentation the linear progress history which is in his opinion perfect. According to a graph Petya has already made, in the first year BerSoft company income must amount to 1 billion bourles, in the second year — 2 billion bourles etc., each following year the income increases by 1 billion bourles. Unfortunately, the real numbers are different from the perfect ones. Among the numbers ai can even occur negative ones that are a sign of the company’s losses in some years. That is why Petya wants to ignore some data, in other words, cross some numbers ai from the sequence and leave only some subsequence that has perfect growth.

Thus Petya has to choose a sequence of years y1, y2, …, yk,so that in the year y1 the company income amounted to 1 billion bourles, in the year y2 — 2 billion bourles etc., in accordance with the perfect growth dynamics. Help him to choose the longest such sequence.

Input
The first line contains an integer n (1 ≤ n ≤ 100). The next line contains n integers ai ( - 100 ≤ ai ≤ 100). The number ai determines the income of BerSoft company in the (2000 + i)-th year. The numbers in the line are separated by spaces.

Output
Output k — the maximum possible length of a perfect sequence. In the next line output the sequence of years y1, y2, …, yk. Separate the numbers by spaces. If the answer is not unique, output any. If no solution exist, output one number 0.

Examples
Input
10
-2 1 1 3 2 3 4 -10 -2 5
Output
5
2002 2005 2006 2007 2010
Input
3
-1 -2 -3
Output
0
求:从1开始,每次+1的最长子串,输出任意答案。答案为其年份。

#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;
int a[300];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int ans[300];
    int cnt=0;
    int now =1;
    for(int i=1;i<=n;i++){
        if(a[i]==now){
            ans[++cnt]=2000+i;
            now++;
        }
    }
    printf("%d\n",cnt);
    for(int i=1;i<=cnt;i++){
        printf("%d%c",ans[i],i==cnt?'\n':' ');
    }
}

D - Cubical Planet CodeForces - 39D
You can find anything whatsoever in our Galaxy! A cubical planet goes round an icosahedral star. Let us introduce a system of axes so that the edges of the cubical planet are parallel to the coordinate axes and two opposite vertices lay in the points (0, 0, 0) and (1, 1, 1). Two flies live on the planet. At the moment they are sitting on two different vertices of the cubical planet. Your task is to determine whether they see each other or not. The flies see each other when the vertices they occupy lie on the same face of the cube.

Input
The first line contains three space-separated integers (0 or 1) — the coordinates of the first fly, the second line analogously contains the coordinates of the second fly.

Output
Output “YES” (without quotes) if the flies see each other. Otherwise, output “NO”.

Examples
Input
0 0 0
0 1 0
Output
YES
Input
1 1 0
0 1 0
Output
YES
Input
0 0 0
1 1 1
Output
NO
题意:问在不同坐标的两个人是否可以看见,只要有一个坐标相同就可以看见。

#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;
int a[5],b[5];

int main()
{
    int cnt = 0;
    for(int i=0;i<3;i++) scanf("%d",&a[i]);
    for(int i=0;i<3;i++){
        scanf("%d",&b[i]);
        if(a[i]!=b[i]) cnt++;
    }
    if(cnt<3){
        printf("YES\n");
    }else printf("NO\n");

    return 0;
}

E - What Has Dirichlet Got to Do with That? CodeForces - 39E
You all know the Dirichlet principle, the point of which is that if n boxes have no less than n + 1 items, that leads to the existence of a box in which there are at least two items.

Having heard of that principle, but having not mastered the technique of logical thinking, 8 year olds Stas and Masha invented a game. There are a different boxes and b different items, and each turn a player can either add a new box or a new item. The player, after whose turn the number of ways of putting b items into a boxes becomes no less then a certain given number n, loses. All the boxes and items are considered to be different. Boxes may remain empty.

Who loses if both players play optimally and Stas’s turn is first?

Input
The only input line has three integers a, b, n (1 ≤ a ≤ 10000, 1 ≤ b ≤ 30, 2 ≤ n ≤ 109) — the initial number of the boxes, the number of the items and the number which constrains the number of ways, respectively. Guaranteed that the initial number of ways is strictly less than n.

Output
Output “Stas” if Masha wins. Output “Masha” if Stas wins. In case of a draw, output “Missing”.

Examples
Input
2 2 10
Output
Masha
Input
5 5 16808
Output
Masha
Input
3 1 4
Output
Stas
Input
1 4 10
Output
Missing
Note
In the second example the initial number of ways is equal to 3125.

If Stas increases the number of boxes, he will lose, as Masha may increase the number of boxes once more during her turn. After that any Stas’s move will lead to defeat.
But if Stas increases the number of items, then any Masha’s move will be losing.
分析;有A个盒子,B个球,一个限制N。如果A^B>=n则输,每个人每次可以选择++A或者++B,S先手。输出输的一方或者平局。

我的思路一开始就出现了问题,我一直觉得从最后的必胜态推向前会出现问题,可队友的记忆化搜索是从正面开始决策的所以没问题。

先打表,找到所有必败态,对于b==1 且a^b

#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string>
#include <algorithm>
using namespace std;
#define LL long long 
const LL maxn = 1234 + 10;
#define INF 0x3f3f3f3f
LL cnt = 0;
LL dp[50000][50];
LL sq[50000][50];
//1 first win


LL dfs(LL a, LL b, LL n)
{
    //if(a>40000) return 1;

    if (sq[a][b] >= n) {
        return dp[a][b] = 1;
    }
    if (b == 1 && sq[a][2] >= n) {
        if ((n - 1 - a) % 2) return dp[a][b] = 1;
        else return dp[a][b] = 2;
    }
    if (a != 1 && b == 1 && dfs(a, b + 1, n) == 2) {
        return dp[a][b] = 1;
    }
    if (dfs(a + 1, b, n) == 2 || dfs(a, b + 1, n) == 2) {
        return dp[a][b] = 1;
    }
    else {
        return dp[a][b] = 2;
    }

}

LL a, b, n;
void init()
{
    for (LL i = 1; i <= 49000; i++) {
        LL now = 1;
        LL j;
        for (j = 1; j <= 40; j++) {
            now = now * i;
            if (now>n + 12312311233) {
                break;
            }
            else {
                sq[i][j] = now;
            }

        }
        for (; j <= 40; j++) {
            sq[i][j] = n + 12312311233;
        }

    }
}

int main()
{

    scanf("%lld%lld%lld", &a, &b, &n);
    init();
    if (a == 1 && sq[a + 1][b] >= n) {
        printf("Missing\n");
    }
    else {
        if (dfs(a + 1, b, n) == 2 || dfs(a, b, n) == 1) {
            printf("Masha\n");
        }
        else {
            printf("Stas\n");
        }
    }



    return 0;
}

F - Pacifist frogs CodeForces - 39F
Thumbelina has had an accident. She has found herself on a little island in the middle of a swamp and wants to get to the shore very much.

One can get to the shore only by hills that are situated along a straight line that connects the little island with the shore. Let us assume that the hills are numbered from 1 to n and the number of a hill is equal to the distance in meters between it and the island. The distance between the n-th hill and the shore is also 1 meter.

Thumbelina is too small to make such jumps. Fortunately, a family of frogs living in the swamp suggests to help her. Each frog agrees to give Thumbelina a ride but Thumbelina should choose only one frog. Each frog has a certain jump length. If Thumbelina agrees to accept help from a frog whose jump length is d, the frog will jump from the island on the hill d, then — on the hill 2d, then 3d and so on until they get to the shore (i.e. find itself beyond the hill n).

However, there is one more problem: mosquitoes also live in the swamp. At the moment they have a siesta, and they are having a nap on some hills. If the frog jumps on a hill with a mosquito the frog will smash it. The frogs Thumbelina has met are pacifists, so they will find the death of each mosquito very much sad. Help Thumbelina choose a frog that will bring her to the shore and smash as small number of mosquitoes as possible.

Input
The first line contains three integers n, m and k (1 ≤ n ≤ 109, 1 ≤ m, k ≤ 100) — the number of hills, frogs and mosquitoes respectively. The second line contains m integers di (1 ≤ di ≤ 109) — the lengths of the frogs’ jumps. The third line contains k integers — the numbers of the hills on which each mosquito is sleeping. No more than one mosquito can sleep on each hill. The numbers in the lines are separated by single spaces.

Output
In the first line output the number of frogs that smash the minimal number of mosquitoes, in the second line — their numbers in increasing order separated by spaces. The frogs are numbered from 1 to m in the order of the jump length given in the input data.

Examples
Input
5 3 5
2 3 4
1 2 3 4 5
Output
2
2 3
Input
1000000000 2 3
2 5
999999995 999999998 999999996
Output
1
2
爱护蚊子的人想让青蛙吃掉尽可能少的蚊子,%判断某个青蛙能吃几个蚊子,输出最少的个/组。

#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;
int n,m,k;
int a[111],b[111];
int cnt[111];
int ans[111];
int mi = 111;
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<m;i++) scanf("%d",&a[i]);
    for(int j=0;j<k;j++) scanf("%d",&b[j]);
    for(int i=0;i<m;i++){
        for(int j=0;j<k;j++){
            if(b[j]%a[i]==0) cnt[i]++;
        }
        if(mi>cnt[i]) mi = cnt[i];
    }
    if(mi==111) mi = 0;
    int ct = 0;
    for(int i=0;i<m;i++){
        if(cnt[i]==mi){
            ans[ct++] = i+1;
        }
    }
    printf("%d\n",ct);
    for(int i=0;i<ct;i++){
        printf("%d%c",ans[i],i==ct-1?'\n':' ');
    }
    return 0;
}

H - Multiplication Table CodeForces - 39H
Petya studies positional notations. He has already learned to add and subtract numbers in the systems of notations with different radices and has moved on to a more complicated action — multiplication. To multiply large numbers one has to learn the multiplication table. Unfortunately, in the second grade students learn only the multiplication table of decimals (and some students even learn it in the first grade). Help Petya make a multiplication table for numbers in the system of notations with the radix k.

Input
The first line contains a single integer k (2 ≤ k ≤ 10) — the radix of the system.

Output
Output the multiplication table for the system of notations with the radix k. The table must contain k - 1 rows and k - 1 columns. The element on the crossing of the i-th row and the j-th column is equal to the product of i and j in the system of notations with the radix k. Each line may have any number of spaces between the numbers (the extra spaces in the samples are put for clarity).

Examples
Input
10
Output
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
Input
3
Output
1 2
2 11

打不同进制的乘法表。

#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;
int a[5],b[5];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        for(int j=1;j<n;j++){
            int num = i * j;
            int ans[10];
            int cnt = 0;
            while(num){
                ans[cnt++] = num % n;
                num /= n;
            }
            if(cnt==1&&j!=1) printf(" ");
            for(int k=cnt-1;k>=0;k--){
                printf("%d",ans[k]);
            }
            if(j==n-1) printf("\n");
            else printf(" ");
        }
    }
    return 0;
}

J - Spelling Check CodeForces - 39J
Petya has noticed that when he types using a keyboard, he often presses extra buttons and adds extra letters to the words. Of course, the spell-checking system underlines the words for him and he has to click every word and choose the right variant. Petya got fed up with correcting his mistakes himself, that’s why he decided to invent the function that will correct the words itself. Petya started from analyzing the case that happens to him most of the time, when all one needs is to delete one letter for the word to match a word from the dictionary. Thus, Petya faces one mini-task: he has a printed word and a word from the dictionary, and he should delete one letter from the first word to get the second one. And now the very non-trivial question that Petya faces is: which letter should he delete?

Input
The input data contains two strings, consisting of lower-case Latin letters. The length of each string is from 1 to 106 symbols inclusive, the first string contains exactly 1 symbol more than the second one.

Output
In the first line output the number of positions of the symbols in the first string, after the deleting of which the first string becomes identical to the second one. In the second line output space-separated positions of these symbols in increasing order. The positions are numbered starting from 1. If it is impossible to make the first string identical to the second string by deleting one symbol, output one number 0.

Examples
Input
abdrakadabra
abrakadabra
Output
1
3
Input
aa
a
Output
2
1 2
Input
competition
codeforces
Output
0
求删除哪一个位置的字母,可以达到字符串匹配。
可以暴力,可以字符串哈希:

暴力AC:

#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;
int a[5],b[5];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        for(int j=1;j<n;j++){
            int num = i * j;
            int ans[10];
            int cnt = 0;
            while(num){
                ans[cnt++] = num % n;
                num /= n;
            }
            if(cnt==1&&j!=1) printf(" ");
            for(int k=cnt-1;k>=0;k--){
                printf("%d",ans[k]);
            }
            if(j==n-1) printf("\n");
            else printf(" ");
        }
    }
    return 0;
}

字符串哈希:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<vector>
using namespace std;
#define ll long long int
#define INF 0x3f3f3f3f
const int maxn = 1e6 + 10;
char a[maxn], b[maxn];
const ll p = 1e9 + 7;
int len1, len2;
ll x[maxn], y[maxn];
int ans[maxn];
ll qkm(ll a, ll b) {
    ll ans = 1;
    while (b > 0) {
        if (b % 2) (ans = ans * a) %= p;
        (a = a * a) %= p;
        b >>= 1;
    }
    return ans;
}
int check(int pos) {
    ll tmp1, tmp2;
    tmp1 = x[pos - 1]; tmp2 = y[pos - 1];
    if (tmp1 != tmp2) return 0;
    //cout << tmp1<<" "<<tmp2 << endl;
    (tmp1 = x[len1 - 1] - (x[pos] * qkm(131, len1 - 1 - pos)) % p + p) %= p;
    (tmp2 = y[len2 - 1] - (y[pos - 1] * qkm(131, len1 - 1 - pos)) % p + p) %= p;
    //cout << tmp1 << " " << tmp2 << endl;
    if (tmp1 != tmp2) return 0;
    return 1;
}
int main()
{
    scanf("%s%s", a, b); int k = 0;
    len1 = strlen(a);
    len2 = strlen(b);
    x[0] = a[0], y[0] = b[0];
    for (int i = 1; i < len1; i++) {
        (x[i] = x[i - 1] * 131 + a[i]) %= p;
    }
    for (int i = 1; i < len2; i++) {
        (y[i] = y[i - 1] * 131 + b[i]) %= p;
    }
    /*for (int i = 0; i < len2; i++) {
        cout << x[i] << " " << y[i] << endl;
    }*/
    if ((x[len1 - 1] - x[0] * qkm(131, len1 - 1) % p + p) % p == y[len2 - 1]) ans[++k] = 1;
    for (int i = 1; i < len1 - 1; i++) {
        if (check(i)) ans[++k] = i + 1;
    }
    if (x[len1 - 2] == y[len2 - 1]) ans[++k] = len1;
    printf("%d\n", k);
    for (int i = 1; i <= k; i++) {
        if (i != 1) printf(" ");
        printf("%d", ans[i]);
    }
    printf("\n");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值