• 【HDOJ】2016年中国大学生程序设计竞赛(杭州)(持续更新)(n^n模板)


    Difference(折半枚举,二分)

    题意:

    f(233,2)=22+32+32=22    x=f(y,K)y   现在给出x,k 求可能的y有多少个

    思路

    0x10^9     1K9       y>10^10时,f(y,k)−y≤0(下面代码是证明过程)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    int sum[20][20];
    ll fum(ll i){
        ll s=0;
        while(i){
            s=s*10+9;
            i--;
        }
        return s;
    }
    int main()
    {
    
        for(int i = 1; i < 10; i++)
        {
            sum[i][0] = 1;
            for(int j = 1; j <= 9; j++)
            {
                sum[i][j] = sum[i][j - 1] * i;
            }
        }
        freopen("out.txt", "w", stdout);
        ll i;
        for(i=8;i<=15;i++){
            if(i*sum[9][9]<fum(i)){
                cout<<i<<endl;
                break;
            }
    
        }
        fclose(stdout);
        return 0;
    }

    输出10

    因为y最长是是个字符,那么就可以把y分成两部分来二分查找(后来知道这种思想叫折半枚举,一部分是前五位,一部分是后五位。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int inf = 0x3f3f3f3f;
    int sum[20][20];
    int num[100007], a[100007];
    
    int main()
    {
        for(int i = 1; i < 10; i++)
        {
            sum[i][0] = 1;
            for(int j = 1; j <= 9; j++)
            {
                sum[i][j] = sum[i][j - 1] * i;
            }
        }
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int T, x, k, temp;
        LL pos;
        cin >> T;
        int mm = 1;
        while(T--)
        {
            LL t;
            pos = 0;
            scanf("%d%d", &x, &k);
            memset(num, 0, sizeof(num));
            for(int i = 1; i < 100000; i++)
            {
                temp = i;
                while(temp)
                {
                    num[i] += sum[temp % 10][k];
                    temp /= 10;
                }
                a[pos++] = num[i] - i;
            }
            sort(a, a + pos);
    
            LL ans = 0;
            for(LL i = 0; i < 100000; i++)
            {
                t = num[i] - i * 100000;
                t = x - t;
    
                temp = lower_bound(a, a + pos, t) - a;
                ans += (upper_bound(a, a + pos, t) - lower_bound(a, a + pos, t));
    
            }
            printf("Case #%d: ", mm++);
            cout<<ans<<endl;
        }
    
        //fclose(stdin);
        //fclose(stdout);
        return 0;
    }

    这个是求n^n模板

    int sum[20][20];
    for(int i = 1; i < 10; i++)
    {
        sum[i][0] = 1;
        for(int j = 1; j <= 9; j++)
        {
            sum[i][j] = sum[i][j - 1] * i;
        }
    }

    Four Operations(思路题)

    题意:输入一行仅由1~9组成的字符串 按照+ - * / 对他们进行操作,求结果之后最大值(12345 max= 1+2-3*4/5=1)

    思路:a+b最大则结果最大,c和d都是一位,e可以是一位可以是两位。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    int sum[20][20];
    /*void powerinit(){
    for(int i=1;i<10;i++){
            sum[i][0]=1;
            for(int j=1;j<=9;j++){
                sum[i][j]=sum[i][j-1]*i;
            }
        }
    }*/
    char s[50];
    int k[50];
    ll fun(int i, int j)
    {
        int it;
        ll s = 0;
        for(it = i; it <= j; it++)
        {
            s = s * 10 + k[it];
        }
        return s;
    }
    int main()
    {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int n, cas, i;
        cin >> n;
        for(cas = 1; cas <= n; cas++)
        {
            cin >> s;
            ll ans=-inf;
            int l=strlen(s);
            for(i = 0; i < l; i++)
            {
                k[i] = s[i] - '0';
            }
            for(i = 1; i < l - 3; i++)
            {
                ll ab, c, d, e;
                ab = max(fun(0, 0) + fun(1, i), fun(0, i - 1) + fun(i, i));
                c = k[i + 1], d = k[i + 2];
                e=fun(i+3,l-1);
                //printf("%lld %lld %lld %lld
    ",ab,c,d,e);
                ans=max(ans,ab-c*d/e);
    
            }
            printf("Case #%d: %lld
    ",cas,ans);
        }
        return 0;
    }

     Car (精度)

    题意:司机开车,速度是一组非递减的序列,然后交警只记录了他的位置,问整段路程的时间

    思路:注意精度问题,就是每次用当前的路程除以速度,然后得到时间的整数,如果这个长度除以这个时间整数不能得到这个速度,那就时间加一,然后算出新的时间,更新时间和答案就行了。

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100100
    #define ll long long
    int T,n;
    
    int num[maxn];
    int main()
    {
        int cas=0;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            num[0]=0;
            for(int i=1;i<=n;i++)  scanf("%d",&num[i]);
    
            ll ans=0;
            double spe=num[n]-num[n-1];
            for(int i=n;i>0;i--)
            {
                double len=(num[i]-num[i-1])*1.0;
                int t=len/spe;
                ans+=t;
                if(len/t!=spe)
                {
                    ans++;
                    spe=len/(t+1);
                }
            }
    
            printf("Case #%d: %lld
    ",++cas,ans);
        }
    
        return 0;
    }

    ArcSoft's Office Rearrangement(贪心,思路(前缀和←不懂诶QAQ))

    题意:

    给你N个数,让你分成K个相等的数,操作有两种:

    ①合并相邻的两个数,得到的数为两个数的和。

    ②分开一个数,得到的两个数为那个数的拆分。

    问最少需要操作多少次。
     
    思路:题解说是用前缀和... 不懂诶( 私は马鹿です)    然后就贪心...(大概要笨死了我这个题我做了两个小时)
       求sum=∑a[i]  再求ave=sum/k    a[i]>k 就看能减去多少个k  a[i]<k 就a[i+1]加到a[i]上(不要忘记把最后结果赋给最新的i)  这种操作都要ans++
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    ll a[100005];
    /*void powerinit(){for(int i=1;i<10;i++){  sum[i][0]=1;  for(int j=1;j<=9;j++)sum[i][j]=sum[i][j-1]*i; }  }*/
    ll gcd(ll a, ll b)
    {
        return b == 0 ? a : gcd(b, a % b);
    }
    int main()
    {
        freopen("in.txt","r",stdin); 
        freopen("out.txt","w",stdout); 
        int T, cas = 1;
        scanf("%d",&T);
        for(; cas <= T; cas++)
        {
            
            int i,n,k;
            ll s = 0;
            scanf("%d%d",&n,&k);
            memset(a, 0, sizeof(a));
            ll ans = 0;
            for(i = 0; i < n; i++)
            {
                scanf("%lld",&a[i]);
                s += a[i];
            }
            if(s % k != 0)
            {
                ans = -1;
            }
            else
            {
                for(i = 0; i < n;)
                {
                    if(a[i] > s / k)
                    {
                        while(a[i]>s/k){
                            ans++;
                               a[i]-=s/k;
                        }
                        
                    }
                    else if(a[i] < s / k)
                    {
                        ll t=i;
                        while(a[t] < s / k)
                        {
                            ans++;
                            a[t] += a[i+1];
                            i++;
                            //cout<<"   "<<a[t]<<endl;
                        }
                        a[i]=a[t];
                    }
                    else
                        i++;
                }
            }
             printf("Case #%d: %lld
    ",cas,ans);
        }
        
        return 0;
    }
  • 相关阅读:
    Lucene.net中的异常处理
    解决lucene 1.* 使用排序后内存溢出问题
    常用的正则表达式
    我的博客开通了
    oracle 常用函数
    破解 office 正版增值计划补丁
    关于dbcommandbuilder的几点说明
    类型转换(一)
    可变数量的参数
    关闭页面时操作数据库
  • 原文地址:https://www.cnblogs.com/Kohinur/p/8982452.html
Copyright © 2020-2023  润新知