Educational Codeforces Round 70 (Rated for Div. 2)

  菜是原罪

A

  题意

  给出两串二进制数,将第二串乘上2^k之后把两串按二进制加起来反转,问k取多少使得结果呈字典序最小。

  题解

  想要反转后字典序最小,也就是把第二串最后1个1的位置与第一串相对应,将其向右移动多少位使得这两个1能对应,(两个1相加时消去变下一位)。

 

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <stack>
#include <map>
#define ull unsigned long long
#define met(a, b) memset(a, b, sizeof(a))
#define lowbit(x) (x&(-x))
#define MID (l + r) / 2
#define ll long long
#define cinint(a) scanf("%d", &a)
#define cinll(a) scanf("%lld", &a)
#define cindouble(a) scanf("%lf", &a)
#define cinstr(a) scanf(" %s", a)
#define coutint(a) printf("%d
", a)
#define coutll(a) printf("%lld
", a)
#define coutdouble(a) printf("%lf
", a)
 
using namespace std;
 
const int maxn = 1e5 + 7;
const ll mod = 1e6 + 3;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
 
int main() {
    int T;
    cin >> T;
    while(T--) {
        string str1, str2;
        cin >> str1 >> str2;
        int len1 = str1.size();
        int len2 = str2.size();
        int i = len1 - 1, j = len2 - 1;
        while(str2[j] != '1') i--, j--;
        while(str1[i] != '1') i--;
        cout << len1 - i - len2 + j << endl;
    }
    return 0;
}

B

  题意

  有一种只有两个按键的计算器,一个增加x,一个增加y。现在给出一串数字,问在以(x, y)(0 <= x, y <= 10)为基础时,最少要添加多少个数使得这一串数字可以被这种计算器输出出来

  题解

  想要使得一串数字成立,也就是去看在串中每两个数字之间需要放入多少个数,那我们可以提前用最短路去处理出任意两个数字在(x, y)(0 <= x, y <= 10)时,从x到y最少需要多少个数,之后暴力去查询就好了。

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <stack>
#include <map>
#define ull unsigned long long
#define ll long long
#define met(a, b) memset(a, b, sizeof(a))
#define lowbit(x) (x&(-x))
#define MID (l + r) / 2

using namespace std;

const int mod = 3e7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 5e3 + 7;

int dp[11][11][11][11];
queue<int> que;

void cal(int i, int j) {
    for(int s = 0; s < 10; s++) {
        while(!que.empty()) que.pop();
        dp[i][j][s][(s+i) % 10] = dp[i][j][s][(s+j) % 10] = 1;
        que.push((s+i) % 10);
        que.push((s+j) % 10);
        while(!que.empty()) {
            int t = que.front();
            que.pop();
            if(dp[i][j][s][(t+i) % 10] == -1) {
                dp[i][j][s][(t+i) % 10] = dp[i][j][s][t] + 1;
                que.push((t+i) % 10);
            }
            if(dp[i][j][s][(t+j) % 10] == -1) {
                dp[i][j][s][(t+j) % 10] = dp[i][j][s][t] + 1;
                que.push((t+j) % 10);
            }
        }
    }
}

int cnt[11][11];

int main() {
    met(dp, -1);
    for(int i = 0; i < 10; i++) {
        for(int j = 0; j < 10; j++) {
            cal(i, j);
        }
    }
    string str;
    cin >> str;
    for(int i = 1; i < str.size(); i++) ++cnt[str[i-1] - '0'][str[i] - '0'];
    for(int i = 0; i < 10; i++) {
        for(int j = 0; j < 10; j++) {
            int flag = 1;
            ll res = 0;
            for(int s = 0; s < 10 && flag; s++) {
                for(int e = 0; e < 10 && flag; e++) {
                    if(!cnt[s][e]) continue;
                    if(dp[i][j][s][e] == -1) {
                        flag = 0;
                        res = -1;
                        break;
                    }
                    res += cnt[s][e]*(dp[i][j][s][e] - 1);
                }
            }
            cout << res << ' ';
        }
        cout << endl;
    }
    return 0;
}

D

  题意

  给出n,让你给出一个串,使得其中子序列为“1337”的有n个。

  题解

  将串都写作1333……1111……337的格式就好了,前面的一个1和后面的37可以组成的个数取决于3也就是(C_m^2)个,后面的一串1与后面的37组成的个数取决于1的个数。

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <stack>
#include <map>
#define ull unsigned long long
#define ll long long
#define met(a, b) memset(a, b, sizeof(a))
#define lowbit(x) (x&(-x))
#define MID (l + r) / 2

using namespace std;

const int mod = 3e7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 5e3 + 7;

int main() {
    int T;
    cin >> T;
    while(T--) {
        int n;
        cin >> n;
        int t = 2;
        while((t-1)*t/2 <= n) ++t;
        --t;
        cout << "1";
        for(int i = 1; i <= t-2; i++) cout << "3";
        t = n - (t-1)*t/2;
        for(int i = 1; i <= t; i++) cout << "1";
        cout << "337" << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Ruby-Z/p/11345983.html