XTU集训第二天16-7-18

花了一个上午把BC A题给A了,妈了个蛋;

原题

问题描述

曾经有一位国王,统治着一片未名之地。他膝下有三个女儿。

三个女儿中最年轻漂亮的当属Psyche。她的父亲不确定她未来的命运,于是他来到Delphi神庙求神谕。

神谕可以看作一个不含前导零的正整数n n n。

为了得到真正的预言,他可以将n n n的各个数位重新排列,并将其分成两个不含前导零的正整数。

请你帮助他求出这两个正整数最大的和。如果不存在这样的两个正整数,输出”Uncertain”.

输入描述

第一行一个整数T T T (1≤T≤10) (1 \le T \le 10) (1≤T≤10),代表数据组数。

接下来T T T行,每行一个正整数n n n (1≤n<1010000000) (1 \le n < 10 ^ {10000000}) (1≤n<10​10000000​​)。

输出描述

对于每组数据,输出一个整数表示最大的和。若不存在一种方案,输出”Uncertain”.

输入样例


112 
233 
1

输出样例

22 
35 
Uncertain

Hint

对于第一组数据,最优方案是将112 112 112分成21 21 21和1 1 1,最大的和为21+1=22 21 + 1 = 22 21+1=22。

对于第二组数据,最优方案是将233 233 233分成2 2 2和33 33 33,最大的和为2+33=35 2 + 33 = 35 2+33=35。

对于第三组数据,显然无法将一个数位分成两部分

一开始卡进位的地方,后来解决了样例和自己测的样例都过了但是WA,最后看别人代码好像是sum出了问题。。最后改了下A了。
#include <cstdio>
#include <iostream>
#include <string>
#include <cctype>
#include <set>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=10000100;
char s[MAXN];
int ans[10];
int ans1[MAXN];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s);
        memset(ans,0,sizeof(ans));
        memset(ans1,0,sizeof(ans1));
        int len=strlen(s);
        for(int i=0;i<len;i++)
        {
            ans[s[i]-'0']++;
        }
        if(ans[0]>len-2)
        {
            printf("Uncertain\n");
           // cout<<ans[0]<<endl;
            continue;
        }
       /* if(len==2)
        {
            int x=s[0]-'0';
            int y=s[1]-'0';
            printf("%d\n",x+y);
            continue;
        }*/
        int kp;
        for(int i=1;i<10;i++)
        {
            if(ans[i])
            {
                kp=i;
                ans[i]--;
                break;
            }
        }
        int sum=0;
        for(int i=0;i<10;i++)
        {
            if(ans[i])
            {
                while(ans[i]--)
                    ans1[sum++]=i;
            }
        }
        ans1[0]+=kp;
        sum=len-2;
        for(int i=0;i<=sum;i++)
        {
            if(ans1[i]>=10)
            {
                ans1[i]-=10;
                ans1[i+1]++;
                if(i==sum)
                    sum++;
            }
        }
        for(int i=sum;i>=0;i--)
        {
            printf("%d",ans1[i]);
        }
        printf("\n");
    }
    return 0;
}
然后下午搞了一下优先队列。。。

  1. 【问题描述】  
  2. 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。  
  3. 因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。  
  4. 例如有3种果子,数目依次为1,2,9。可以先将 1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为 12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。  
  5. 【输入文件】  
  6. 输入文件fruit.in包括两行,第一行是一个整数n(1 <= n <= 10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1 <= ai <= 20000)是第i种果子的数目。  
  7. 【输出文件】  
  8. 输出文件fruit.out包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。  
  9. 【样例输入】  
  10. 3  
  11. 1 2 9  
  12. 【样例输出】  
  13. 15  
  14. 【数据规模】  
  15. 对于30%的数据,保证有n <= 1000;  
  16. 对于50%的数据,保证有n <= 5000;  
  17. 对于全部的数据,保证有n <= 10000。
  18.    
    #include <bits/stdc++.h>
    using namespace std;
    
    struct cmp
    {
        bool operator()(const int &a,const int &b)
        {
            return a>b;
        }
    };
    int main()
    {
        priority_queue<int,vector<int>,cmp>que;
        int n;
        int a;
        int sum;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
        	scanf("%d",&a);
        	que.push(a);
        }
        sum=0;
        while(n>=2)
        {
        	int x=que.top();
        	que.pop();
        	int y=que.top();
        	que.pop();
        	sum+=x+y;
        	que.push(x+y);
        	n--;
        }
        printf("%d\n",sum);
        return 0;
    
    }
    
    挺简单的优先队列。不过用到了重载。。学到了新技能....
  19. 一天下来累啊累啊,总是想休息。。看到别人一直再敲,自己也停不下来



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值