A题 简单的模拟。给出一个数,输出它的英文名就好,注意零。
#include
#include
using namespace std;
int main()
{
int n;
scanf("%d",&n);
if(n==0||n==1||n==2||n==3||n==4||n==5||n==6||n==7||n==8||n==9||n==10||n==11||n==12||n==13||n==14||n==15||n==16||n==17||n==18||n==19||n==20||n==30||n==40||n==50||n==60||n==70||n==80||n==90)
{
switch(n)
{
case 0:printf("zero\n");break;
case 1:printf("one\n");break;
case 2:printf("two\n");break;
case 3:printf("three\n");break;
case 4:printf("four\n");break;
case 5:printf("five\n");break;
case 6:printf("six\n");break;
case 7:printf("seven\n");break;
case 8:printf("eight\n");break;
case 9:printf("nine\n");break;
case 10:printf("ten\n");break;
case 11:printf("eleven\n");break;
case 12:printf("twelve\n");break;
case 13:printf("thirteen\n");break;
case 14:printf("fourteen\n");break;
case 15:printf("fifteen\n");break;
case 16:printf("sixteen\n");break;
case 17:printf("seventeen\n");break;
case 18:printf("eighteen\n");break;
case 19:printf("nineteen\n");break;
case 20:printf("twenty\n");break;
case 30:printf("thirty\n");break;
case 40:printf("forty\n");break;
case 50:printf("fifty\n");break;
case 60:printf("sixty\n");break;
case 70:printf("seventy\n");break;
case 80:printf("eighty\n");break;
case 90:printf("ninety\n");break;
}
}
else
{
string str,s1,s2;
if(n%10==1) s2="one";
if(n%10==2) s2="two";
if(n%10==3) s2="three";
if(n%10==4) s2="four";
if(n%10==5) s2="five";
if(n%10==6) s2="six";
if(n%10==7) s2="seven";
if(n%10==8) s2="eight";
if(n%10==9) s2="nine";
if((n/10)%10==2) s1="twenty";
if((n/10)%10==3) s1="thirty";
if((n/10)%10==4) s1="forty";
if((n/10)%10==5) s1="fifty";
if((n/10)%10==6) s1="sixty";
if((n/10)%10==7) s1="seventy";
if((n/10)%10==8) s1="eighty";
if((n/10)%10==9) s1="ninety";
str=s1+"-"+s2;
cout<
<
B题 数学题,是二进制法表示数这一类问题的变形。二进制表示数确实有很多优势,在计数上可以达到很大的值。在于领会二进制法的精髓吧,所以代码有时候作为语言的能力甚至超过了言辞。
#include
#include
#include
using namespace std;
int main()
{
string str;
cin>>str;
int len=str.length();
int m=atoi(str.c_str());
int tmp=1;
int ans=0;
while(m)
{
if(m%10==4)
ans+=1*tmp;
else if(m%10==7)
ans+=2*tmp;
tmp=tmp*2;
m/=10;
}
printf("%d\n",ans);
}
C题 分治题,用二分法解。读题是一个艰难的过程。给出一等差数列si=A+(i-1)*B;n次询问,每次询问给出l,t,m。题目要求,取数列中l开始的m个数,每次对每个数减一,减t次,到零就停止,求为零的最右边的数的下标是多少。
二分就是要找到二分的区间以及二分结束的判断条件。显然可以得到最右端的数是lr=(t-a)/b+1,最左端的数是ll=l。且只要sl+(sl+1)+(sl+2)+...+(smid)<=t*m;就可以将二分区间向右移动,否则向左。需要注意的是longlong ==
#include
#include
using namespace std;
typedef long long ll;
ll a,b,n;
ll l,t,m;
ll sum(ll r)
{
return (2*a+(l+r-2)*b)*(r-l+1)/2;
}
int main()
{
scanf("%I64d%I64d%I64d",&a,&b,&n);
while(n--)
{
scanf("%I64d%I64d%I64d",&l,&t,&m);
ll sl=a+(l-1)*b;
if(sl>t)
{
printf("-1\n");
continue;
}
else
{
ll ll=l,lr=(t-a)/b+1,mid;
while(ll<=lr)
{
mid=(ll+lr)/2;
if(sum(mid)<=t*m) ll=mid+1;
else lr=mid-1;
}
printf("%I64d\n",ll-1);
}
}
return 0;
}