zoukankan      html  css  js  c++  java
  • 2017西电第一次省赛选拔赛补题

    https://vjudge.net/contest/161101#overview


    A.判断B是否能整除A的每一个素因子。

    #include<bits/stdc++.h>
    using namespace std;
    
    int prime[1000005],vis[1000005] = {0};
    long long a,b;
    
    int main()
    {
        ios::sync_with_stdio(false);
        int T,z = 0;
        cin >> T;
        int cnt = 0;
        for(int i = 2;i <= 1000000;i++)
        {
            if(!vis[i]) prime[++cnt] = i;
            for(int j = 1;i*prime[j] <= 1000000 && j <= cnt;j++)
            {
                vis[prime[j]*i] = 1;
                if(i%prime[j] == 0) break;
            }
        }
        while(T--)
        {
            cin >> a >> b;
            cout << "Case #" << ++z << ": ";
            int flag = 0;
            for(int i = 1;(long long)prime[i]*prime[i] <= a;i++)
            {
                if(a%prime[i] == 0)
                {
                    while(a%prime[i] == 0)  a /= prime[i];
                    if(b%prime[i]) flag = 1;
                }
            }
            if(b%a) flag = 1;
            if(flag)    cout << "NO" << endl;
            else    cout << "YES" << endl;
        }
        return 0;
    }
    View Code

    B.显然,最优解是每次选择一个人就把他HP耗尽。假设只有两个人,则

    先攻击第一个人消耗:DPS1HP1+DPS2(HP1+HP2)

    先攻击第二个人消耗:DPS2HP2+DPS1(HP1+HP2)

    可以得出当DPS1/HP1 > DPS2/HP2时,攻击第一个人消耗小。

    由此推广到n个人的情况,按DPSi/HPi排序即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n;
    struct xx
    {
        int hp,dps;
        friend bool operator <(xx a,xx b)
        {
            return a.dps*b.hp > a.hp*b.dps;
        }
    }a[25];
    
    int main()
    {
        ios::sync_with_stdio(false);
        while(cin >> n)
        {
            for(int i = 1;i <= n;i++)   cin >> a[i].dps >> a[i].hp;
            sort(a+1,a+1+n);
            int ans = 0,sum = 0;
            for(int i = 1;i <= n;i++)
            {
                sum += a[i].hp;
                ans += sum*a[i].dps;
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code

    C.先把前一半的密文翻译乘明码,KMP求后半的在前半的最长前缀。

    #include<bits/stdc++.h>
    using namespace std;
    
    string s,ss;
    int nextt[200005];
    map<char,char> mp;
    
    void get_next(string s)
    {
        int len = s.length();
        int i = 0,j = -1;
        nextt[0] = -1;
        while(i < len)
        {
            if(j == -1 || s[i] == s[j]) nextt[++i] = ++j;
            else    j = nextt[j];
        }
    }
    
    int main()
    {
        int T;
        cin >> T;
        while(T--)
        {
            cin >> ss >> s;
            for(int i = 0;i < ss.length();i++)  mp[ss[i]] = i+'a';
            int len = s.length(),endd = (len+1)/2;
            string sss = s;
            for(int i = 0;i < endd;i++) s[i] = mp[s[i]];
            s.insert(endd,1,'+');
            get_next(s);
            int cnt = len-nextt[len+1];
            for(int i = 0;i < cnt;i++)  cout << sss[i];
            for(int i = 0;i < cnt;i++)  cout << mp[sss[i]];
            cout << endl;
        }
        return 0;
    }
    View Code

    D.set模拟,注意连续在一个点吃的时候,方向不改变。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,m,cnt[100005];
    set<int> s;
    set<int>::iterator it;
    
    int main()
    {
        ios::sync_with_stdio(false);
        int T,z = 0;
        cin >> T;
        while(T--)
        {
            s.clear();
            memset(cnt,0,sizeof(cnt));
            cin >> n >> m;
            int dir = 2,now = 0;
            long long ans = 0;
            while(m--)
            {
                int a,b;
                cin >> a;
                if(a == 0)
                {
                    cin >> b;
                    if(cnt[b] == 0) s.insert(b);
                    cnt[b]++;
                }
                else
                {
                    if(s.size() == 0)   continue;
                    it = s.lower_bound(now);
                    int x = 1e9,y = 1e9;
                    if(it != s.end())   y = *it-now;
                    if(it != s.begin())
                    {
                        it--;
                        x = now-*it;
                        it++;
                    }
                    if(it != s.end() && now == *it);
                    else if(x < y || x == y && dir == 1)
                    {
                        it--;
                        ans += x;
                        dir = 1;
                    }
                    else
                    {
                        ans += y;
                        dir = 2;
                    }
                    now = *it;
                    cnt[*it]--;
                    if(cnt[*it] == 0)   s.erase(it);
                }
            }
            cout << "Case " << ++z << ": " << ans << endl;
        }
    }
    View Code

    E.因为每两个点之间有且只有一条单向边,拓扑排序判断是否存在环即可,有环肯定有三元环。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,in[2005];
    string s;
    vector<int> v[2005];
    
    bool topsort()
    {
        int cnt = 0;
        while(cnt < n)
        {
            int t;
            for(t = 1;t <= n;t++)
            {
                if(in[t] == 0)  break;
            }
            if(t == n+1)    return 1;
            in[t]--;
            cnt++;
            for(int i = 0;i < v[t].size();i++)
            {
                in[v[t][i]]--;
            }
        }
        return 0;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        int T,z = 0;
        cin >> T;
        while(T--)
        {
            cin >> n;
            for(int i = 1;i <= n;i++)   v[i].clear();
            memset(in,0,sizeof(in));
            for(int i = 1;i <= n;i++)
            {
                cin >> s;
                s = " "+s;
                for(int j = 1;j < s.length();j++)
                {
                    if(s[j] == '1') in[j]++;
                    v[i].push_back(j);
                }
            }
            cout << "Case #" << ++z << ": ";
            if(topsort())   cout << "Yes" << endl;
            else    cout << "No" << endl;
        }
        return 0;
    }
    View Code

    F.逆序建树就可以了。

    #include<iostream>
    using namespace std;
    
    struct xx
    {
        xx *l,*r;
        char x;
    }*root;
    string s[10005];
    
    void insertt(xx *&p,char x)
    {
        if(p == NULL)
        {
            p = new xx;
            p->l = NULL;
            p->r = NULL;
            p->x = x;
            return;
        }
        if(p->x > x)    insertt(p->l,x);
        else    insertt(p->r,x);
    }
    
    void printff(xx *p)
    {
        if(!p)  return;
        cout << p->x;
        printff(p->l);
        printff(p->r);
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        while(1)
        {
            int n = 0;
            while(cin >> s[++n] && s[n] != "*" && s[n] != "$");
            root = NULL;
            for(int i = n-1;i >= 1;i--)
            {
                for(int j = 0;j < s[i].length();j++)    insertt(root,s[i][j]);
            }
            printff(root);
            cout << endl;
            if(s[n] == "$") break;
        }
        return 0;
    }
    View Code

    G.Bretschneider公式

    #include<bits/stdc++.h>
    using namespace std;
    
    int a,b,c,d;
    
    int main()
    {
        ios::sync_with_stdio(false);
        int T,z = 0;
        cin >> T;
        while(T--)
        {
            cin >> a >> b >> c >> d;
            if(a+b+c <= d || a+c+d <= b || a+b+d <= c || b+c+d <= a)
            {
                cout << "Case " << ++z << ": -1" << endl;
                continue;
            }
            double t = (double)(a+b+c+d)/2;
            double ans = sqrt((t-a)*(t-b)*(t-c)*(t-d));
            cout << "Case " << ++z << ": " << fixed << setprecision(6) << ans << endl;
        }
        return 0;
    }
    View Code

    H.找规律打个表。

    #include<bits/stdc++.h>
    using namespace std;
    
    long long n,a[50000];
    
    int main()
    {
        ios::sync_with_stdio(false);
        for(int i = 1;i <= 50000;i++) a[i] = (long long)i*(i-1);
        int T;
        cin >> T;
        while(T--)
        {
            cin >> n;
            int t = lower_bound(a+1,a+50000,n)-a-1;
            long long ans1 = (long long)t*t+n-a[t];
            long long ans2 = 0,now = 1;
            while(now*now < ans1)   ans2 += (now*now-(now-1)*(now-1))*(now-1),now++;
            ans2 += (ans1-(now-1)*(now-1)+1)*(now-1);
            cout << ans1 << " " << ans2 << endl;
        }
        return 0;
    }
    View Code

    I.直接模拟加法。

    #include<bits/stdc++.h>
    using namespace std;
    
    string s;
    int a[100005];
    
    int main()
    {
        ios::sync_with_stdio(false);
        int T;
        cin >> T;
        while(T--)
        {
            memset(a,0,sizeof(a));
            cin >> s;
            int sum = 0,cnt = 0;
            for(int i = s.length()-1;i >= 0;i--)
            {
                a[++cnt] = s[i]-'0';
                sum += a[cnt];
            }
            sum %= 10;
            do
            {
                if(a[1] != 9)
                {
                    a[1]++;
                    sum = (sum+1)%10;
                }
                else
                {
                    int t = 1;
                    a[1] = 0;
                    sum = 0;
                    for(int i = 2;i <= cnt;i++)
                    {
                        if(t)
                        {
                            a[i]++;
                            if(a[i] == 10)  a[i] = 0;
                            else    t = 0;
                        }
                        sum += a[i];
                    }
                    if(t)
                    {
                        a[++cnt] = 1;
                        sum++;
                    }
                    sum %= 10;
                }
            }while(sum != 0);
            int t = 100004;
            while(a[t] == 0)   t--;
            while(t >= 1)
            {
                cout << a[t];
                t--;
            }
            cout << endl;
        }
        return 0;
    }
    View Code

    J.把所有U替换成I,打表所有可能的个数。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,ok[3000008];
    string s;
    
    int main()
    {
        ios::sync_with_stdio(false);
        int now = 1;
        while(now <= 3000000)
        {
            ok[now] = 1;
            now *= 2;
        }
        for(int i = 3000000;i >= 1;i--)
        {
            if(ok[i+6])   ok[i] = 1;
        }
        int T;
        cin >> T;
        while(T--)
        {
            cin >> s;
            int flag = 0,sum = 0;
            if(s[0] != 'M') flag = 1;
            for(int i = 1;i < s.length();i++)
            {
                if(s[i] == 'M') flag = 1;
                else if(s[i] == 'U')    sum += 3;
                else    sum++;
            }
            if(flag == 0 && ok[sum])    cout << "Yes" << endl;
            else    cout << "No" << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    常用工具
    H5页面验收流程及性能验收标准
    埋点数据测试
    提高效率的必备工具
    移动APP安全测试
    Response响应相关
    AES加密解密
    Requests模块
    爬虫入门
    【CMDB】API传输验证
  • 原文地址:https://www.cnblogs.com/zhurb/p/6810809.html
Copyright © 2011-2022 走看看