九野的博客,转载请注明出处 :http://blog.csdn.net/acmmmm/article/details/11115751
题目链接 :http://222.197.181.5/problem.php?pid=1808
题意:T个测试数据
a,b,c 表示有 a个1,b个2,c个5
问:由上述不能组成的最小正整数是多少
思路1:模拟做
用a个1组成一串连续的数字[0,a]
然后从中取出k ( 0<=k<=a) 和 2换一下就有连续的一个序列,再把换出来的1放回去,所以有一串连续序列 [0, r1] ( r1= a+ Min(a,b) )
同理再把5放进这个序列,这样依次操作,当连续序列不再改变或者 a,b,c用完时 r1就是能组成的最大的正整数
mark:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <queue>
#include <stdlib.h>
#include <cstdlib>
#include <math.h>
#include <set>
#include <vector>
#define inf 100000000
#define N 200200
#define ll long long
using namespace std;
inline ll Max(ll a,ll b){return a>b?a:b;}
inline ll Min(ll a,ll b){return a<b?a:b;}
ll a,b,c,ans;
ll coin,temp,r1;
bool dfs(){
bool success=false;
temp=ans;
coin=0;
if(b)
{
r1=ans+2*Min(b,ans);
if(r1!=ans){
b-=Min(b,ans);
ans=temp=r1;
success=true;
}
else return success;
}
if(c)
{
r1=ans+Min(ans/4,c);
if(r1!=ans)
{
temp=Max(temp,r1);
coin=Min(ans/4,c);
success=true;
}
else return success;
r1=ans+2*Min(ans/3,coin);
if(r1!=ans)
{
temp=Max(temp,r1);
success=true;
}
else return success;
r1=ans+3*Min(ans/2,coin);
if(r1!=ans)
{
temp=Max(temp,r1);
success=true;
}
else return success;
r1=ans+4*Min(ans,coin);
if(r1!=ans)
{
temp=Max(temp,r1);
success=true;
}
else return success;
r1=ans+5*coin;
if(r1!=ans)
{
temp=Max(temp,r1);
success=true;
}
else return success;
}
return success;
}
int main(){
int T,Cas=1;scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld",&a,&b,&c);
ans=a+2*Min(a,b);
b-=Min(a,b);
a=0;
while(dfs()==true)
{
ans=temp;
c-=coin;
if(b+c==0)break;
}
printf("Case #%d: %lld\n",Cas++,ans+1);
}
return 0;
}
/*
99
1 1 1
1 2 1
0 1 1
1 0 1
1 1 0
1000000 0 0
0 1000000 0
0 0 1000000
5 2 1
5 10 1
456 12341 5648
45 154 87
451 23487 415664764
45645665 1545613 458664
10586 4788 451
15420 546 451
12 21285 1544
ans:
4
11
1
2
4
1000001
1
1
15
31
53379
789
2078371246
51030212
22418
18768
1544
50303
*/
思路2:若1和2能构成>=4,则所有整数(<= a+b*2+c*5)都能组成,答案就是 a+b*2+c*5 +1
借的代码:
#include<stdio.h>
int main()
{
long long a,b,c,d,n;
scanf("%lld",&n);
int t=1;
while(n--)
{
scanf("%lld%lld%lld",&a,&b,&c);
if(a==0)
d=1;
else if(a+b*2<4)
{
d=a+b*2+1;
}
else
d=c*5+a+b*2+1;
printf("Case #%d: %lld\n",t++,d);
}
return 0;
}