zoukankan      html  css  js  c++  java
  • 2016 CCPC Hangzhou Onsite

    A:题意:n个格子排成一排,每个a[i],要求重排成k个,每个人数相同,合并两个和划分成两个(可以不等)都是花费为1,问最小花费

    题解:从前往后贪心即可,由于哪个地方忘开ll,wa了,全改成ll就过了

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double eps=1e-6;
    const int N=100000+10,maxn=5000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    ll a[N],n,k;
    void solve(ll x)
    {
        ll ans=0,res=0;
        for(int i=1;i<=n;i++)
        {
            if(res!=0)ans++,a[i]+=res;
            if(a[i]>=x)
            {
                ll te=a[i]/x;
                if(a[i]%x==0)te--;
                ans+=te;
                res=a[i]%x;
            }
            else res=a[i];
        }
        printf("%lld
    ",ans);
    }
    int main()
    {
        int T;scanf("%d",&T);
        for(int _=1;_<=T;_++)
        {
            scanf("%lld%lld",&n,&k);
            ll sum=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%lld",&a[i]);
                sum+=a[i];
            }
            printf("Case #%d: ",_);
            if(sum%k!=0)puts("-1");
            else solve(sum/k);
        }
        return 0;
    }
    /********************
    
    ********************/
    View Code

    B:题意:n个炸弹,引爆需要花费,引爆后会引爆范围内的炸弹,问最小花费

    题解:强连通缩点求dag上度数最小的点,(队友写的,细节不清楚)

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int,int>
    #define piii pair<int,pair<int,int>>
    
    using namespace std;
    
    const int N = 1000 + 7;
    const int M = 1e4 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    
    int n, idx, top, cnt, id[N], dfn[N], st[N], low[N], deg[N];
    LL cost[N];
    bool in[N];
    
    
    struct Point {
        LL x, y, r, c;
    } p[N];
    
    vector<int> edge[N];
    
    
    void tarjan(int u) {
        st[top++] = u; ++idx;
        low[u] = dfn[u] = idx;
        in[u] = true;
    
        for(int v : edge[u]) {
            if(!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            } else if(in[v]) {
                low[u] = min(low[u], dfn[v]);
            }
        }
    
        if(low[u] == dfn[u]) {
            cnt++;
            while(1) {
                int now = st[--top];
                in[now] = false;
                id[now] = cnt;
                cost[cnt] = min(cost[cnt], p[now].c);
                if(now == u) break;
            }
        }
    }
    
    void init() {
        idx = 0; top = 0; cnt = 0;
        memset(deg, 0, sizeof(deg));
        memset(cost, inf, sizeof(cost));
        memset(dfn, 0, sizeof(dfn));
        memset(in, 0, sizeof(in));
        for(int i = 1; i <= n; i++)
            edge[i].clear();
    }
    
    LL dis(LL a, LL b, LL c, LL d) {
        return ((a - c) * (a - c) + (b - d) * (b - d));
    }
    int main() {
        int T; scanf("%d", &T);
        for(int cas = 1; cas <= T; cas++) {
            init();
            scanf("%d", &n);
            for(int i = 1; i <= n; i++)
                scanf("%lld%lld%lld%lld", &p[i].x, &p[i].y, &p[i].r, &p[i].c);
    
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= n; j++) {
                    if(i == j) continue;
                    if(dis(p[i].x, p[i].y, p[j].x, p[j].y) <= p[i].r * p[i].r) {
                        edge[i].push_back(j);
                    }
                }
            }
    
    
            for(int i = 1; i <= n; i++) {
                if(!dfn[i]) tarjan(i);
            }
    
            for(int u = 1; u <= n; u++) {
                for(int v : edge[u]) {
                    if(id[u] != id[v]) {
                        deg[id[v]]++;
                    }
                }
            }
    
            LL ans = 0;
    
            for(int i = 1; i <= cnt; i++)
                if(deg[i] == 0)
                    ans += cost[i];
            printf("Case #%d: ", cas);
            printf("%lld
    ", ans);
        }
        return 0;
    }
    /*
    */
    View Code

    C:题意:有一辆车,n个记录点,要求车速度只能增加,每次通过记录点的时间为整数,问通过n个记录点的最小时间

    题解:把加速看成一瞬间,其他都是匀速,那么有vi=si/ti<=si+1/ti+1,可得ti>=si*ti+1/si+1,从后往前贪心即可

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 10007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double eps=1e-6;
    const int N=100000+10,maxn=5000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    ll a[N],b[N];
    int main()
    {
        int T;scanf("%d",&T);
        for(int _=1;_<=T;_++)
        {
            int n;scanf("%d",&n);
            a[0]=0;
            for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
            for(int i=0;i<n;i++)b[i]=a[i+1]-a[i];
            ll ans=1,last=1;
            for(int i=n-2;i>=0;i--)
            {
                int now=b[i]*last/b[i+1];
                if(b[i]*last%b[i+1]!=0)now++;
                last=now;
                ans+=last;
            }
            printf("Case #%d: %lld
    ",_,ans);
        }
        return 0;
    }
    /********************
    
    ********************/
    View Code

    D:题意:f(y,k)代表y的每一位的k次方之和,给你x,k求满足x=f(y,k)-y的对数

    题解:折半枚举,把前5位预处理出来,然后枚举后5位算答案

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=10+10,maxn=1000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    int x,kk;
    int f[11][11];
    map<ll,int>m[10];
    void prepare()
    {
        for(int i=1;i<=9;i++)
        {
            f[i][0]=1;
            for(int j=1;j<=10;j++)f[i][j]=f[i][j-1]*i;
        }
        for(int kk=1;kk<=9;kk++)
        {
            for(int i=0;i<=99999;i++)
            {
                ll te=0,ii=i,now=100000;
                for(int j=5;j<=9;j++)
                {
                    te+=f[ii%10][kk]-(ii%10)*now;
                    ii/=10;now*=10ll;
                }
                m[kk][te]++;
            }
        }
    }
    void solve()
    {
        ll ans=0;
        for(int i=0;i<=99999;i++)
        {
            ll te=0,ii=i,now=1;
            for(int j=0;j<=4;j++)
            {
                te+=f[ii%10][kk]-(ii%10)*now;
                ii/=10;now*=10ll;
            }
            if(m[kk].find(x-te)!=m[kk].end())ans+=m[kk][x-te];
        }
        printf("%lld
    ",ans-(x==0));
    }
    int main()
    {
        prepare();
        int T;scanf("%d",&T);
        for(int _=1;_<=T;_++)
        {
            scanf("%d%d",&x,&kk);
            printf("Case #%d: ",_);
            solve();
        }
        return 0;
    }
    /***********************
    
    ***********************/
    View Code

    E:题意:给1到9的每个数字出现次数,你每次选3个数构成x+y=z的等式,问不同的等式最多有多少个

    题解:爆搜+剪枝,枚举20种方程,x+y=z,y+x=z算一种,加的时候分开算即可,剪枝:当前方程数+剩余数字数/3<最大答案,剩余方程数+当前方程<最大答案,

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double eps=1e-6;
    const int N=1000000+10,maxn=5000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    int eq[20][3]={
    {1,1,2},
    {1,2,3},
    {1,3,4},
    {1,4,5},
    {1,5,6},
    {1,6,7},
    {1,7,8},
    {1,8,9},
    {2,2,4},
    {2,3,5},
    {2,4,6},
    {2,5,7},
    {2,6,8},
    {2,7,9},
    {3,3,6},
    {3,4,7},
    {3,5,8},
    {3,6,9},
    {4,4,8},
    {4,5,9}
    };
    int a[10],res[20];
    void dfs(int a[],int id,int now,int &ans)
    {
        int sum=0;
        for(int i=1;i<=9;i++)
        {
            if(a[i]<0)return ;
            else sum+=a[i];
        }
        if(sum/3+now<ans)return ;
        if(res[id]+now<ans)return ;
        if(id==20)
        {
            ans=max(ans,now);
            return ;
        }
        dfs(a,id+1,now,ans);
        if(a[eq[id][0]]>=1&&a[eq[id][1]]>=1&&a[eq[id][2]]>=1)
        {
            a[eq[id][0]]--;a[eq[id][1]]--;a[eq[id][2]]--;
            dfs(a,id+1,now+1,ans);
            a[eq[id][0]]++;a[eq[id][1]]++;a[eq[id][2]]++;
        }
        if(eq[id][0]!=eq[id][1]&&a[eq[id][0]]>=2&&a[eq[id][1]]>=2&&a[eq[id][2]]>=2)
        {
            a[eq[id][0]]-=2;a[eq[id][1]]-=2;a[eq[id][2]]-=2;
            dfs(a,id+1,now+2,ans);
            a[eq[id][0]]+=2;a[eq[id][1]]+=2;a[eq[id][2]]+=2;
        }
    }
    int main()
    {
        for(int i=19;i>=0;i--)
        {
            if(eq[i][0]==eq[i][1])res[i]=res[i+1]+1;
            else res[i]=res[i+1]+2;
        }
        int T;scanf("%d",&T);
        for(int _=1;_<=T;_++)
        {
            for(int i=1;i<=9;i++)scanf("%d",&a[i]);
            int ans=0;
            dfs(a,0,0,ans);
            printf("Case #%d: %d
    ",_,ans);
        }
        return 0;
    }
    /********************
    
    ********************/
    View Code

    F:题意:给一个1到9组成的字符串,按顺序插入+-*/,求最大的数

    题解:由于*/优先级高,而且又是被减的,故越小越好,*/插在最后两位即可,注意有6位时,可能有问题,比如,111991,特判掉就好了,前面的+也是,选一个一位数,和剩余的加看哪个大就选哪个

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 12345678
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double eps=1e-6;
    const int N=300+10,maxn=5000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    char s[N];
    ll cal(int a,int b)
    {
        ll ans=0;
        for(int i=a;i<=b;i++)
            ans=ans*10+(s[i]-'0');
        return ans;
    }
    int main()
    {
        int T;scanf("%d",&T);
        for(int _=1;_<=T;_++)
        {
            printf("Case #%d: ",_);
            scanf("%s",s);
            int n=strlen(s);
            ll ans1=cal(0,0)+cal(1,n-4)-cal(n-3,n-3)*cal(n-2,n-2)/cal(n-1,n-1);
            ll ans2=cal(0,n-5)+cal(n-4,n-4)-cal(n-3,n-3)*cal(n-2,n-2)/cal(n-1,n-1);
    
            if(n==6){
            long long ans=-1e18;
            for(int i=0;i<n-1;i++)
                for(int j=i+1;j<n-1;j++)
                    for(int k=j+1;k<n-1;k++)
                        for(int u=k+1;u<n-1;u++){
                            //printf("%d %d %d %d
    ",i,j,k,u);
                            ans1=max(ans1,cal(0,i)+cal(i+1,j)-cal(j+1,k)*cal(k+1,u)/cal(u+1,n-1));
                        }
    
    
            }
            printf("%lld
    ",max(ans1,ans2));
        }
        return 0;
    }
    View Code

    j:题意:求1到n的每一个数的2的质因子和,

    题解:对于每个数x来说可以化成p1^c1*...*pk^ck,对于2^k来说就等价于∑(d|x)|μ(d)|,根据莫比乌斯函数的性质,μ(d)=(-1)^k,d=p1*p2...pk,相当于每次只选k个质因子,然后因为可能为负数,所以变成∑(d|x)μ(d)^2

    ∑(1<=i<=n)∑(d|i)μ(d)^2,假设j^2是d的最大平方因子,那么∑(k|j)μ(k)=∑(k^2|j^2)μ(k)=∑(k^2|d)μ(k),所以∑(1<=i<=n)∑(d|i)∑(k^2|d)μ(d)=∑(1<=i<=n)μ(k)∑(k^2|d)[n/(k^2)],因为k>sqrt(n)时后面变成了0,所以只需要算前sqrt(n)即可,记忆化后面,μ预处理出来

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double eps=1e-6;
    const int N=1000000+10,maxn=5000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    ll n,f[N];
    int prime[N],mu[N];
    bool notprime[N];
    void init()
    {
        int cnt=0;mu[1]=1;
        for(int i=2;i<N;i++)
        {
            if(!notprime[i])prime[++cnt]=i,mu[i]=-1;
            for(int j=1;j<=cnt&&i*prime[j]<N;j++)
            {
                notprime[i*prime[j]]=1;
                mu[i*prime[j]]=-mu[i];
                if(i%prime[j]==0){mu[i*prime[j]]=0;break;}
            }
        }
    }
    ll cal(ll n)
    {
        if(n<N&&f[n])return f[n];
        ll ans=0;
        for(ll i=1,j;i<=n;i=j+1)
        {
            j=n/(n/i);
            ans+=n/i*(j-i+1)%mod;
            ans%=mod;
        }
        if(n<N)f[n]=ans;
        return ans;
    }
    int main()
    {
        init();
        int T;scanf("%d",&T);
        for(int _=1;_<=T;_++)
        {
            scanf("%lld",&n);
            printf("Case #%d: ",_);
            ll ans=0;
            for(ll i=1;i<=n/i;i++)
            {
                if(mu[i]==0)continue;
                ans+=mu[i]*cal(n/i/i)%mod;
                ans=(ans%mod+mod)%mod;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    /********************
    
    ********************/
    View Code

    K:题意:给你s,n,问你s+1....s+n能不能每个对应一个因子是1到n,而且1到n每个只出现一次

    题解:因为如果s+1到s+n和1到n有重叠,那么就选自己,然后剩余的数每个数和因子连边,二分图匹配即可,(也是队友写的)

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int,int>
    #define piii pair<int,pair<int,int>>
    
    using namespace std;
    
    const int N = 500 + 7;
    const int M = 1e4 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    
    int T, n, s, match[N];
    bool edge[N][N], vis[N];
    
    bool path(int u) {
        for(int v = 1; v <= n; v++) {
            if(edge[u][v] && !vis[v]) {
                vis[v] = true;
                if(!match[v] || path(match[v])) {
                    match[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main() {
        scanf("%d", &T);
        for(int cas = 1; cas <= T; cas++) {
            memset(match, 0, sizeof(match));
            memset(edge, 0, sizeof(edge));
            scanf("%d%d", &n, &s);
    
            if(s == 0 || s == 1) {
                printf("Case #%d: ", cas);
                puts("Yes");
                continue;
            }
    
            int l1 = 1, r1 = n;
            int l2 = s + 1, r2 = s + n;
            if(r1 >= l2) {
                swap(l2, r1);
                l2++; r1--;
            }
    
            n = r2 - l2 + 1;
            if(n > 500) {
                printf("Case #%d: ", cas);
                puts("No");
            } else {
                for(int i = l2; i <= r2; i++) {
                    for(int j = l1; j <= r1; j++) {
                        if(i % j == 0) {
                            edge[i - l2 + 1][j - l1 + 1] = true;
                        }
                    }
                }
                bool flag = true;
                for(int i = 1; i <= n; i++) {
                        memset(vis, 0, sizeof(vis));
                        if(!path(i)) {
                        flag = false;
                        break;
                    }
                }
                printf("Case #%d: ", cas);
                if(flag) puts("Yes");
                else puts("No");
            }
        }
        return 0;
    }
    /*
    */
    View Code
  • 相关阅读:
    采集智能电表
    未能写入输出文件“c:\WINDOWS\Microsoft.NET\Framework\.....dll”“拒绝访问。
    随笔写写jquery
    随便写写,,
    写写Ajaxpro
    C# 给程序加日志功能。
    Oracle_Database_11g_标准版_企业版__下载地址_详细列表
    通过C#发送自定义的html格式邮件
    C# 加密解密链接字符串
    获取本地 有线 正在使用的网卡信息
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9088649.html
Copyright © 2011-2022 走看看