• Comet OJ


    A 双十一特惠 (简单版)

     n  <=  1e19,   1e9 > 1(8)

    https://www.cometoj.com/contest/79/problem/A?problem_id=4198

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int main(){
        int t; cin >> t; 
        while(t--) {
            int cnt1 = 0; 
            int n;cin >> n;
            int pr[] = {1,11,111,1111,11111,111111,1111111,11111111,111111111};
            for(int i = 8; i >= 0; i--) {
                cnt1 += n/pr[i];
                n %= pr[i];
            }
            if(cnt1 > 9) cout << "Impossible
    ";
            else cout << cnt1 << endl;
        }
        return 0;
    }

    D 困难版

    https://www.cometoj.com/contest/79/analysis // dm聚聚在线讲题, 走过路过不要错过

    https://atcoder.jp/contests/agc011/tasks/agc011_e    //类似的题目,AtCoder Grand 011E Increasing Numbers

     可以假设一个 特殊的进制, 1 11 111 1111 …………

     然后将十进制数转为这个进制, 比如说 234 -> 2,1,1(2*111+1*11+1) 

     该进制下的位数相加为所需要的 “好的数” 的数量,  我们会发现当除了最后一位其他位数 大于9时, 可以转化为更小的该进制
     比如说    11,0,0 ->  1,0,10,0   10,0,1,0 ->1,0,0,0,10  
     然后我们可以将第i个进制为i , 取该进制下的贡献

     11,0,0 ->  1,0,10,0(11*3=33   1*4+10*1=14)   10,0,1,0 ->1,0,0,0,10 (10*4+2=42   1*5+10=15) 
     会发现当有位数大于9时(非末位)转化为更小的进制 贡献更小, 所以我们可以一直将他转化为更小的  故符合贪心选择性质
     结论: 将一个十进制数用“好的数”表示时, 尽可能用当前满足的最大的“好的数”表示,  所耗费的“好的数”数量最少

     题解: 将 u = v*9 ,用尽量少的10i -1 数来表示u, 需要尽量少的 1 可以让 u 表示为 若干个10的幂次方之和,

     u+x =  10a1+10a2+10a3+……+10ax, 所以u+x的各位数之和<= x, x<=1e7 所以可以直接暴力枚举x

     (  更详细的证明 可以参照这个博客 https://blog.csdn.net/Orzage/article/details/85015246)  O(n)  --位数

    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <cmath>
    #define _for(i,a,b) for(int i = (a); i < (b); i++)
    #define _rep(i,a,b) for(int i = (a); i <= (b); i++)
    #define _per(i,a,b) for(int i = (a); i > (b); i--)
    void solve(){
        std::string s; std::cin >> s;
        int n = s.size(), sum = 0;
        std::vector<int> v(n+2, 0);
        _rep(i,1,n) v[i] = (s[i-1]-'0')*9;
        _per(i,n-1,0) v[i-1] += v[i]/10, v[i] %= 10;
        _rep(i,0,n) sum += v[i];
        _rep(p,1,1e6){
            int i = n;
            while(v[i] >= 9) v[i--] -= 9, sum -= 9;
            sum++, v[i]++;
            if(p >= sum && p%9 == sum%9) {
                std::cout << p << '
    ';
                return;
            }
        }
    }
    
    int main(){
        int t; std::cin >> t;
        while(t--) solve();
        return 0;
    }

    B 当我们同心在一起 

    https://www.cometoj.com/contest/79/problem/B?problem_id=4199

    #include<bits/stdc++.h>
    #define ll long long
    //暴力枚举每个坐标作为圆心的情况下 能有几个距离圆心距离相等的点,ans += f[cnt1]
    //将每个点作为圆心 其他点到圆心的距离作为数组 sort 再求有几个, 浮点数精度会有误差 所以把距离函数改成 ll 不取平方根就可以ac
    //也可以将每次得到的距离用 map存, O(t*n2
    using namespace std; ll dist(ll x1, ll y1, ll x2, ll y2){ return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int main(){ int t; t = 1; //cin >> t; while(t--) { int n;cin >> n; int ans = 0; //vector<pair<int, int> > dot(n+1); ll dx[2020], dy[2020]; for(int i = 0; i < n; i++) cin >> dx[i] >> dy[i]; for(int i = 0; i < n; i++) { int x = i; vector<ll> dis; for(int j = 0; j < n; j++){ if(i == j) continue; ll distan = dist(dx[i], dy[i], dx[j], dy[j]); dis.push_back(distan); //cout << "i = " << i << " dis = " << distan << endl << endl; } sort(dis.begin(), dis.end()); ll y = -1; int cnt1 = 1; for(int j = 0; j < n-1; j++){ //cout << dis[j] << " y = " << y << " cnt1 = " << cnt1 << endl << endl; if(dis[j] == y) cnt1++; else { ans += (cnt1*(cnt1-1)*(cnt1-2)/6); y = dis[j]; cnt1 = 1; } } //cout << "ans = " << ans << " cnt1= "<< cnt1<< " f[cnt1]" << f[cnt1] << endl << endl; ans += (cnt1*(cnt1-1)*(cnt1-2)/6); //cout << "!111 "; } cout << ans << endl; } return 0; }
    #include<bits/stdc++.h>
    #define ll long long
    //看了题解, 稍微优化了下
    using namespace std;
    ll dist(ll x1, ll y1, ll x2, ll y2){return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
    int main(){
        int t; 
        t = 1;
        while(t--) {
            int n;cin >> n;
            int ans = 0;
            //vector<pair<int, int> > dot(n+1);
            ll dx[2020], dy[2020];
            for(int i = 0; i < n; i++) cin >> dx[i] >> dy[i];
            for(int i = 0; i < n; i++) {
                vector<ll> dis;
                for(int j = 0; j < n; j++){
                    dis.push_back(dist(dx[i], dy[i], dx[j], dy[j]));
                }
                sort(dis.begin(), dis.end());
                for(int j = 0, k; j < n; j = k){
                    for(k = j; dis[k] == dis[j]; k++);
                    ans += (k-j)*(k-j-1)*(k-j-2)/6;
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
  • 相关阅读:
    [Docker]一键部署gitlab中文版
    [Docker]python 2.7.5 docker-compose安装
    [CentOS7]pip安装
    快速傅里叶变换FFT
    HDU 4734 f(x)
    DP
    HDU 3555 Bomb
    HDU 5898 odd-even number
    将文本拷贝到剪贴板
    数论分块
  • 原文地址:https://www.cnblogs.com/163467wyj/p/11939346.html
Copyright © 2020-2023  润新知