zoukankan      html  css  js  c++  java
  • 【训练赛】ICPC Central Russia Regional Contest (CRRC 18)

    C Dimensions

    题目传送门:

    https://codeforces.com/gym/102785/problem/C

    题意:

    给一串字符,有‘*’‘/’‘()’,输出约分后的分子和分母。按照给定的字典序输出

    思路

    用栈读入,存放,约分。map储存。唯一要注意的是,约完是输出1.

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int kMaxN = 1005;
    string s;
    inline bool cmp(char a, char b) {
        if (tolower(a) != tolower(b))
            return tolower(a) < tolower(b);
        return a < b;
    }
    struct String {
        string s;
        String(const string &_s) {
            s = _s;
        }
        inline bool operator<(const String &other) const {
            for (int i = 0; i < min((int)s.length(), (int)other.s.length()); ++i) {
                if (s[i] == other.s[i])
                    continue;
                return cmp(s[i], other.s[i]); 
            }
            return s.length() < other.s.length();
        }
    };
    
    map<String, int> mp[2];
    void resolve(int l, int r, int d) {
        for (int i = l, c = d; i <= r; ) {
            
            if (s[i] == '*') {
                c = d;
                ++i;
            } else if (s[i] == '/') {
                c = d ^ 1;
                ++i;
            } else if (s[i] == '(') {
                int p = 1, j;
                for (j = i + 1; j <= r; ++j) {
                    if (s[j] == '(')
                        ++p;
                    if (s[j] == ')')
                        --p;
                    if (p == 0)
                        break;
                }
                resolve(i + 1, j - 1, c);
                i = j + 1;
            } else {
                int j;
                for (j = i; j <= r; ++j) {
                    if (!isalpha(s[j]))
                        break;
                }
                ++mp[c][s.substr(i, j - i)];
                i = j;
            }
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin >> s;
        resolve(0, s.length() - 1, 0);
        for (auto it : mp[0]) {
            if (mp[1][it.first] > 0) {
                int c = min(mp[1][it.first], mp[0][it.first]);
                mp[1][it.first] -= c;
                mp[0][it.first] -= c;
            }
        }
        bool first = true;
        for (auto it : mp[0]) {
            while (it.second--) {
                if (!first)
                    cout << "*" << it.first.s;
                else {
                    cout << it.first.s;
                    first = false;
                }
            }
        }
        if (first)
            cout << 1;
        cout << endl;
        first = true;
        for (auto it : mp[1]) {
            while (it.second--) {
                if (!first)
                    cout << "*" << it.first.s;
                else {
                    cout << it.first.s;
                    first = false;
                }
            }
        }
        if (first)
            cout << 1;
        cout << endl;
        return 0;
    }
    

    D We were trying to share an orange

    题目传送门:

    https://codeforces.com/gym/102785/problem/D

    题意:

    给一个数k,输出最小的因子个数为k个的数

    思路:

    找规律发现若k是质数,则答案是2^(k-1),其他结果可以进行搜索。因为k<1000,因此要用高精度.

    代码实现:

    #include <bits/stdc++.h>
    using namespace std;
    int a[20]={2,3,5,7,11,13,17,19,23,29};
    string ans="1";
    string mul(string a, int b)
    {
        const int L = 505;
        int na[L];
        string ans;
        int La = (int)a.size();
        fill(na, na + L, 0);
        for (int i = La - 1; i >= 0; i--) na[La - i - 1] = a[i] - '0';
        int w = 0;
        for (int i = 0; i < La; i++){
            na[i] = na[i] * b + w;
            w = na[i] / 10;
            na[i] = na[i] % 10;
        }
        while (w) {
            na[La++] = w % 10;
            w /= 10;
        }
        La--;
        while (La >= 0) ans += na[La--] + '0';
        return ans;
    }
    
    bool cmp(string x,string y){
        if(x.length()==y.length()){
            return x<y;
        }
        else return x.length()<y.length();
    }
    
    void dfs(string s,int k,int up,int ii){
        if(k==1){
            if(cmp(s,ans))ans=s;
        }
        for(int i=2;i<=min(k,up);i++){
            if(k%i==0){
                string ss=s;
                for(int j=1;j<i;j++){
                    ss=mul(ss,a[ii]);
                    if(cmp(ans,ss))return;
                }
                dfs(ss,k/i,i,ii+1);
            }
        }
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=0;i<450;i++)ans+='0';
        dfs("1",n,n,0);
        cout<<ans<<endl;
        return 0;
    }
    

    H、A self-describing sequence

    题目传送门:

    https://codeforces.com/gym/102785/problem/H

    题意:

    给定一个k,构造一个序列,满足原序列是0-(k-1),且构造序列对应原序列是原序列的数在构造序列的个数。如:

    0 1 2 3

    1 2 1 0

    0在构造序列的个数是1,1在构造序列的个数为2,2在构造序列的个数为1,3在构造序列的个数为0

    如果没有这个序列,则输出0;
    给定一个n,输入n个数,输出这n个数对应的构造序列的数字。

    思路:

    我们找规律可以发现,当k=1,2,3,6的时候,答案无解。

    当k=4和5的时候需要特殊构造(手动构造就好)

    当k>=7时,a[0]=k-4 a[1]=2 a[2]=1 a[k-1]=1 其他为0.

    代码实现:

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    using namespace std;
    const int N=1e5+3; 
    ll k,n,a[N];
    int main(){
    	scanf("%lld%lld",&k,&n);
    	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    	if(k==1 || k==2 || k==3 ||k==6)
    		printf("0
    ");
    	else if(k==4) {
    		printf("%lld
    ",n);
    		for(int i=1;i<=n;i++) {
    			if(a[i] == 0) printf("1 ");
    			else if(a[i] == 1) printf("2 ");
    			else if(a[i] == 2) printf("1 ");
    			else if(a[i] == 3) printf("0 ");
    		}
    	}
    	else if(k==5) {
    		printf("%lld
    ",n);
    		for(int i=1;i<=n;i++) {
    			if(a[i]==0) printf("2 ");
    			else if(a[i]==1) printf("1 ");
    			else if(a[i]==2) printf("2 ");
    			else printf("0 ");
    		}
    	}
    	else {
    		printf("%lld
    ",n);
    		for(int i=1;i<=n;i++) {
    			if(a[i]==0) printf("%lld ",k-4);
    			else if(a[i]==1) printf("2 ");
    			else if(a[i]==2) printf("1 ");
    			else if(a[i]==k-4) printf("1 ");
    			else printf("0 ");
    		}
    	}
    	return 0;
    }
    

    对于构造题,如果半个小时都没有思路,在赛场上应该选择放弃。构不出来就是构不出来。如果想解除构造题,应该不只是想,更需要借助其他代码进行打表或者搜索,来寻找规律(大佬一眼看出。

  • 相关阅读:
    mycat主要参数
    Linux上通过docker方式安装mysql
    Docker镜像拉取慢的解决方法
    mysql关联、子查询索引优化
    Mysql优化单表查询
    Mysql如何快速插入100万条记录?
    git连接到github
    git分支操作2
    git基本操作1
    git简介及安装(win10)
  • 原文地址:https://www.cnblogs.com/Shayndel/p/14177214.html
Copyright © 2011-2022 走看看