2022年暑假ACM热身练习3(部分题目总结)

A - A == B ?

Give you two numbers A and B, if A is equal to B, you should print "YES", or print "NO".

Input

each test case contains two numbers A and B.

Output

for each case, if A is equal to B, you should print "YES", or print "NO".

Sample

InputcopyOutputcopy
 
1 2
2 2
3 3
4 3
 
NO
YES
YES
NO

总结:乍一看是个水题,结果提交几次都不过,要用字符串处理。

#include<cstdio>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<cmath>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;

int main()
{
	char a[1000000],b[1000000];//数字的大小设置比较大
	int a1,b1,i;
	while(scanf("%s%s",a,b)!=EOF)
	{
	   a1=strlen(a);
	   b1=strlen(b);
	  if(strchr(a,'.')!=NULL)//在a中查找‘.’
	  {
	  	
	    for(i=a1-1;a[i]=='0';i--)//从字符串的末尾查找,如果是‘0’则将其设置为空,不是则退出循环
		
		    
		        a[i]='\0';
				if(a[i]=='.')//如果有小数点则去除
				
		        a[i]='\0';
		   


}
	 if(strchr(b,'.')!=NULL)//同理
	  {
	  	
	    for( i=b1-1;b[i]=='0';i--)
		
		    
		        b[i]='\0';
				if(b[i]=='.')
					b[i]='\0';
			
		


	  }
	
	if(strcmp(b,a)==0)//比较a和b,如果相同则返回0
		cout<<"YES"<<endl;
	else
		cout<<"NO"<<endl;
	
	
 
}
return 0;
} 

B - An easy problem

 HDU - 2055 

we define f(A) = 1, f(a) = -1, f(B) = 2, f(b) = -2, ... f(Z) = 26, f(z) = -26;
Give you a letter x and a number y , you should output the result of y+f(x).

Input

On the first line, contains a number T.then T lines follow, each line is a case.each case contains a letter and a number.

Output

for each case, you should the result of y+f(x) on a line.

Sample

InputcopyOutputcopy
 
6
R 1
P 2
G 3
r 1
p 2
g 3
 
19
18
10
-17
-14
-4

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<cstdlib>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
	 for(int i=0;i<n;i++)
	 {
	  int m=0,s1=0;
	  char s;
	  cin>>s>>m;
	  if('A'<=s&&s<='Z')
	   {  s1=m+s-64;
	    
	  }
	  else
		  {s1=m+(-1)*(s-96);
	  } 
	  cout<<s1<<endl;
	 }

}

return 0;
}

C - Rectangles

Given two rectangles and the coordinates of two points on the diagonals of each rectangle,you have to calculate the area of the intersected part of two rectangles. its sides are parallel to OX and OY .

Input

Input The first line of input is 8 positive numbers which indicate the coordinates of four points that must be on each diagonal.The 8 numbers are x1,y1,x2,y2,x3,y3,x4,y4.That means the two points on the first rectangle are(x1,y1),(x2,y2);the other two points on the second rectangle are (x3,y3),(x4,y4).

Output

Output For each case output the area of their intersected part in a single line.accurate up to 2 decimal places.

Sample

InputcopyOutputcopy
 
1.00 1.00 3.00 3.00 2.00 2.00 4.00 4.00
5.00 5.00 13.00 13.00 4.00 4.00 12.50 12.50
 
1.00
56.25

总结:长度之和减去端点之距离等于重复的边长.

#include<cstdio>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<cmath>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef double de;
int cmp(const void *a,const void *b)
{


	return *(double *)a>*(double *)b?1:-1;//double排序的特殊用法
}
int main()
{  
	de x1,x2,x3,x4,y1,y2,y3,y4;
	while(~scanf("%lf %lf %lf %lf %lf %lf %lf %lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4))
	{
		
	double	a[4]={x1,x2,x3,x4};
	double	b[4]={y1,y2,y3,y4};
	    qsort(a,4,sizeof(a[0]),cmp);
		qsort(b,4,sizeof(b[0]),cmp);//快速排序
		de n,m,s;
		n=abs(x1-x2)+abs(x3-x4)-(a[3]-a[0]);
		m=abs(y1-y2)+abs(y3-y4)-(b[3]-b[0]);//两个长方形的长减去两个长方形端点坐标
	  if(n<0||m<0)
		  s=0.0;
	  else
		  s=n*m;
	  printf("%.2f\n",s);
	}

	
return 0;
} 

D - A + B Again

There must be many A + B problems in our HDOJ , now a new one is coming.
Give you two hexadecimal integers , your task is to calculate the sum of them,and print it in hexadecimal too.
Easy ? AC it !

Input

The input contains several test cases, please process to the end of the file.
Each case consists of two hexadecimal integers A and B in a line seperated by a blank.
The length of A and B is less than 15.

Output

For each test case,print the sum of A and B in hexadecimal in one line.

Sample

InputcopyOutputcopy
 
+A -A
+1A 12
1A -9
-1A -12
1A -AA
 
0
2C
11
-2C
-90
#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
using namespace std;
int main()
{   string s5="0123456789ABCDEF";
	string s3,s4;
	while(cin>>s3>>s4)
	{
	 string s6="";
	 long long s7=0;
	 long long s1=0,s2=0;
	 int k1=1,k2=1,t1=0,t2=0;
	 if(s3[0]=='-')
	 {k1=-1;t1=1;}
	 if(s3[0]=='+')
	 {
	   t1=1;
	 }
	 if(s4[0]=='-')
	 { k2=-1;t2=1;}
	 if(s4[0]=='+')
	 {
	 t2=1;
	 }
	 for(int i=t1;i<s3.size();i++)
	 {
	    if(s3[i]=='A')
		   s1+=pow(16,s3.size()*1.0-i-1)*10;
		if(s3[i]=='B')
		   s1+=pow(16,s3.size()*1.0-i-1)*11;
		if(s3[i]=='C')
		   s1+=pow(16,s3.size()*1.0-i-1)*12;
		if(s3[i]=='D')
		   s1+=pow(16,s3.size()*1.0-i-1)*13;
		if(s3[i]=='E')
		   s1+=pow(16,s3.size()*1.0-i-1)*14;
		if(s3[i]=='F')
		   s1+=pow(16,s3.size()*1.0-i-1)*15;
		if(s3[i]>='0'&&s3[i]<='9')
			s1+=(s3[i]-'0')*pow(16,s3.size()*1.0-i-1);
	  
	 }
	 for(int i=t2;i<s4.size();i++)
	 {
	    if(s4[i]=='A')
		   s2+=pow(16,s4.size()*1.0-1-i)*10;
		if(s4[i]=='B')
		   s2+=pow(16,s4.size()*1.0-1-i)*11;
		if(s4[i]=='C')
		   s2+=pow(16,s4.size()*1.0-1-i)*12;
		if(s4[i]=='D')
		   s2+=pow(16,s4.size()*1.0-i-1)*13;
		if(s4[i]=='E')
		   s2+=pow(16,s4.size()*1.0-i-1)*14;
		if(s4[i]=='F')
		   s2+=pow(16,s4.size()*1.0-i-1)*15;
		if(s4[i]>='0'&&s4[i]<='9')
			s2+=(s4[i]-'0')*pow(16,s4.size()*1.0-i-1);
	  
	 }
	
	 s7=k1*s1+s2*k2;
	 
	 if(s7<0)
		 cout<<"-";
	 if(s7==0)
	 {
	 cout<<0<<endl;
	 continue;
	 }
	 s7=abs(s7);
	while(s7!=0)
	{
	 s6+=s5[s7%16];
	 s7=s7/16;
	}
	
	for(int j=s6.size()-1;j>=0;j--)
		
		cout<<s6[j];
	cout<<endl;
	
	
	}

return 0;
}

E - The sum problem

Given a sequence 1,2,3,......N, your job is to calculate all the possible sub-sequences that the sum of the sub-sequence is M.

Input

Input contains multiple test cases. each case contains two integers N, M( 1 <= N, M <= 1000000000).input ends with N = M = 0.

Output

For each test case, print all the possible sub-sequence that its sum is M.The format is show in the sample below.print a blank line after each test case.

Sample

InputcopyOutputcopy
 
20 10
50 30
0 0
[1,4]
[10,10]

[4,8]
[6,9]
[9,11]
[30,30]

总结:利于数列求和公式推出了设i为开始,j表示第几项,则有(i+i+j-1)/2=m;j>=1;所以(2*i-1)*j+j*j=2*m;所以j<=sqrt(2*m.0.5);i=(2*m-j*j+j)/(2*j);

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
typedef long long ll;
using namespace std;
int main()
{  
    ll n,m;
    while(cin>>n>>m)
    {
     if(n==m&&n==0)
         break;
    ll i=0,j=0;
    for(j=pow(2*m,0.5);j>=1;j--)
    {
     i=(2*m-j*j+j)/(2*j);
     if((2*i+j-1)*j==2*m)
    cout<<"["<<i<<","<<i+j-1<<"]"<<endl;
    }
    cout<<endl;
    }
    
return 0;
} 

F - 龟兔赛跑

据说在很久很久以前,可怜的兔子经历了人生中最大的打击――赛跑输给乌龟后,心中郁闷,发誓要报仇雪恨,于是躲进了杭州下沙某农业园卧薪尝胆潜心修炼,终于练成了绝技,能够毫不休息得以恒定的速度(VR m/s)一直跑。兔子一直想找机会好好得教训一下乌龟,以雪前耻。
最近正值HDU举办50周年校庆,社会各大名流齐聚下沙,兔子也趁此机会向乌龟发起挑战。虽然乌龟深知获胜希望不大,不过迫于舆论压力,只能接受挑战。
比赛是设在一条笔直的道路上,长度为L米,规则很简单,谁先到达终点谁就算获胜。
无奈乌龟自从上次获胜以后,成了名龟,被一些八卦杂志称为“动物界的刘翔”,广告不断,手头也有了不少积蓄。为了能够再赢兔子,乌龟不惜花下血本买了最先进的武器――“"小飞鸽"牌电动车。这辆车在有电的情况下能够以VT1 m/s的速度“飞驰”,可惜电池容量有限,每次充满电最多只能行驶C米的距离,以后就只能用脚来蹬了,乌龟用脚蹬时的速度为VT2 m/s。更过分的是,乌龟竟然在跑道上修建了很多很多(N个)的供电站,供自己给电动车充电。其中,每次充电需要花费T秒钟的时间。当然,乌龟经过一个充电站的时候可以选择去或不去充电。
比赛马上开始了,兔子和带着充满电的电动车的乌龟并列站在起跑线上。你的任务就是写个程序,判断乌龟用最佳的方案进军时,能不能赢了一直以恒定速度奔跑的兔子。

Input

本题目包含多组测试,请处理到文件结束。每个测试包括四行:
第一行是一个整数L代表跑道的总长度
第二行包含三个整数N,C,T,分别表示充电站的个数,电动车冲满电以后能行驶的距离以及每次充电所需要的时间
第三行也是三个整数VR,VT1,VT2,分别表示兔子跑步的速度,乌龟开电动车的速度,乌龟脚蹬电动车的速度
第四行包含了N(N<=100)个整数p1,p2...pn,分别表示各个充电站离跑道起点的距离,其中0<p1<p2<...<pn<L
其中每个数都在32位整型范围之内。

Output

当乌龟有可能赢的时候输出一行 “What a pity rabbit!"。否则输出一行"Good job,rabbit!";
题目数据保证不会出现乌龟和兔子同时到达的情况。

Sample

InputcopyOutputcopy
 
100
3 20 5
5 8 2
10 40 60
100
3 60 5
5 8 2
10 40 60
Good job,rabbit!
What a pity rabbit!

总结:利于动态规划,算每一次加油站需要的时间。

#include<iostream>
#include<string>
#include<stdlib.h>
#include<cstdio>
#include<math.h>
#include<algorithm>
typedef long long ll;
double c[1000];//起点到加油站用的时间
using namespace std;
int main()
{
	int L;
	while(cin>>L){
	int N,C,T;
     cin>>N>>C>>T;
	 int VR,VT1,VT2;
	 cin>>VR>>VT1>>VT2;
	 int h[1000];//起点到加油站的距离
	 for(int i=1;i<=N;i++)
		 cin>>h[i];
	 memset(c,0,sizeof(c));
	 h[N+1]=L;//为了方便计算,将起点和终点也算进去
	 h[0]=0;
	 double time=0;
	 for(int i=1;i<=N+1;i++)
	 {
		  c[i]=10000000000000;//设每一个i到起点时间为无穷大
	 for(int j=0;j<i;j++)		 
	{	
		
		int len=h[i]-h[j];//求i到j 加油站的距离
		if(j==0)//j==0时不需要考虑加不加油
		{
		 if(len>C)
		  c[i]=min(c[i],C*1.0/VT1+(len-C)*1.0/VT2);//采用滚动数组,将空间降为一维
		 else
			 c[i]=min(c[i],len*1.0/VT1);
		}
		else//j>0考虑加油
		{
		 if(len>C)
			 c[i]=min(c[i],C*1.0/VT1+(len-C)*1.0/VT2+c[j]+T);
		 else
		    c[i]=min(c[i],len*1.0/VT1+c[j]+T);
		
		}
	 }
	 
	 }
	 double s=L*1.0/VR;//兔子的时间固定
	
	 
	 if(s>c[N+1])
		 cout<<"What a pity rabbit!"<<endl;
	 else
		 cout<<"Good job,rabbit!"<<endl;
	}
    return 0;
}

G - Snooker

background:
Philip likes to play the QQ game of Snooker when he wants a relax, though he was just a little vegetable-bird. Maybe you hadn't played that game yet, no matter, I'll introduce the rule for you first.
There are 21 object balls on board, including 15 red balls and 6 color balls: yellow, green, brown, blue, pink, black.
The player should use a white main ball to make the object balls roll into the hole, the sum of the ball's fixed value he made in the hole is the player's score. The player should firstly made a red ball into the hole, after that he gains red-ball's value(1 points), then he gets the chance to make a color ball, then alternately. The color ball should be took out until all the red-ball are in the hole. In other word, if there are only color balls left on board, the player should hit the object balls in this order: yellow(2 point), green(3 point), brown(4 point), blue(5 point), pink(6 point), black(7 point), after the ball being hit into the hole, they are not get out of the hole, after no ball left on board, the game ends, the player who has
the higher score wins the game. PS: red object balls never get out of the hole.
I just illustrate the rules that maybe used, if you want to contact more details, visit http://sports.tom.com/snooker/ after
the contest.

for example, if there are 12 red balls on board(if there are still red ball left on board, it can be sure that all the color
balls must be on board either). So suppose Philp can continuesly hit the ball into the hole, he can get the maximun score is
12 * 1 (12 red-ball in one shoot) + 7 * 12(after hit a red ball, a black ball which was the most valuable ball should be the target) + 2 + 3 + 4 + 5 + 6 + 7(when no red ball left, make all the color ball in hole).
Now, your task is to judge whether Philip should make the decision to give up when telling you the condition on board(How many object balls still left not in the hole and the other player's score). If Philp still gets the chance to win, just print "Yes", otherwise print "No". (PS: if the max score he could get on board add his current score is equal to the opponent's current score, still output "Yes")

Input

The first line contains a numble N indicating the total conditions. Then followed by N lines, each line is made of three integers:
Ball_Left P_Score O_Score represeting the ball number left on board, Philp's current score, and the opponent's current score.
All the input value are in 32 bit integer value range.

Output

You should caculate the max score left Philp can gain, and judge whether he has the possiblity to win.

Sample

InputcopyOutputcopy
 
2
12 1 1
1 30 39
 
Yes
No

总结:理解题目就好说了,题目是剩下的球大于6个才有红色的球,否则只能依次用有颜色的球.

#include<iostream>
#include<string>
#include<stdlib.h>
#include<cstdio>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<vector>
typedef long long ll;
using namespace std;
int a[6]={7,6,5,4,3,2};//从高的往低的,应为求最高分
int main()
{
	int n;
	while(cin>>n)
	{
	 for(int i=0;i<n;i++){
		int ball_left,p,e,s=0;
	 cin>>ball_left>>p>>e;
	   
	 if(ball_left>6)
	 {
	 s=27+8*(ball_left-6);
	 }
	 else
	 {
	  for(int i=0;i<ball_left;i++)
	  {
	   s+=a[i];
	  }
	 }
	 if(s+p>=e)
		 cout<<"Yes"<<endl;
	 else
		 cout<<"No"<<endl;
	 }
	
	
	
	}
	
	return 0;
}

H - Treasure the new start, freshmen!

background:
A new semester comes , and the HDU also meets its 50th birthday. No matter what's your major, the only thing I want to tell you is:"Treasure the college life and seize the time." Most people thought that the college life should be colorful, less presure.But in actual, the college life is also busy and rough. If you want to master the knowledge learned from the book, a great deal of leisure time should be spend on individual study and practise, especially on the latter one. I think the every one of you should take the learning attitude just as you have in senior school.
"No pain, No Gain", HDU also has scholarship, who can win it? That's mainly rely on the GPA(grade-point average) of the student had got. Now, I gonna tell you the rule, and your task is to program to caculate the GPA.
If there are K(K > 0) courses, the i-th course has the credit Ci, your score Si, then the result GPA is
GPA = (C1 * S1 + C2 * S2 +……+Ci * Si……) / (C1 + C2 + ……+ Ci……) (1 <= i <= K, Ci != 0)
If there is a 0 <= Si < 60, The GPA is always not existed.

Input

The first number N indicate that there are N test cases(N <= 50). In each case, there is a number K (the total courses number), then K lines followed, each line would obey the format: Course-Name (Length <= 30) , Credits(<= 10), Score(<= 100).
Notice: There is no blank in the Course Name. All the Inputs are legal

Output

Output the GPA of each case as discribed above, if the GPA is not existed, ouput:"Sorry!", else just output the GPA value which is rounded to the 2 digits after the decimal point. There is a blank line between two test cases.

Sample

InputcopyOutputcopy
 
2
3
Algorithm 3 97
DataStruct 3 90
softwareProject 4 85
2
Database 4 59
English 4 81
 
90.10

Sorry!

总结:注意输出格式即可

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<sstream>
using namespace std;
double round(double r)//四舍五入
{

 return r>0.0?floor(r+0.5):floor(r-0.5);
}
int main()
{  
	int n;
	while(cin>>n)
	{
	 for(int i=0;i<n;i++)
	 {
		string s[1000];
		double a[10000],b[10000];
	 int m,flag=1;
	 double s1=0,s2=0,s3=0;
	 cin>>m;
	 for(int j=0;j<m;j++)
	 {
	  cin>>s[j]>>a[j]>>b[j];
	  s1+=a[j]*b[j];
	  s2+=a[j];
	   if(b[j]<60)//如果有成绩小于60的直接标记
	   {
	   flag=0;
	   }
	 }
	 s3=s1/s2;
	 s3=round(s3*100);//精确小数点后两位四舍五入
	 if(flag!=0){
	 printf("%.2f\n",s3/100);
	
	 }
	 else
	 {
	 cout<<"Sorry!"<<endl;//有标记的直接输出sorry
	   
	 }
	 if(i<n-1)//数据之间有一行空格
	 cout<<endl;
	 
	 }
	
	}
return 0;
}

I - Subset sequence

 (待补)

J - 过山车

 HDU - 2063 

RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。聪明的Acmer,你可以帮忙算算最多有多少对组合可以坐上过山车吗?

Input

输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。

Output

对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。

Sample

InputcopyOutputcopy
 
6 3 3
1 1
1 2
1 3
2 1
2 3
3 1
0
 
3

#include<iostream>
#include<string>
#include<stdlib.h>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<vector>
typedef long long ll;
double c[1000];
using namespace std;
vector<int>p[10000];//和女孩配对的男孩
	int link[5000];//和男生在一起的女孩
	bool vis[5000];//男生有无伴侣的状态
bool solve(int girl)
{
    for(int j=0;j<p[girl].size();j++)//遍历女孩子中意的男孩子
	{	int v=p[girl][j];
           if(!vis[v])//判断男孩子的有无伴侣的状态
		   {
			   vis[v]=true;//假设伴侣状态为true,最终是否合适还要考察
		      if(link[v]==-1||solve(link[v]))//判断这个男孩子是否还有其他的女孩子牵手成功
			  {
			     link[v]=girl;//牵手成功
				 return true;
			  
			  }
		   
		   }
	     
	}
	return false;

}
int main()
{
	
	int k,m,n;
	while(cin>>k)
	{
		if(k==0)
		  break;
		cin>>m>>n;
	  
	  int girl,boy,ans=0;
	 for(int i=0;i<10000;i++)
		 p[i].clear();//清理
	for(int i=0;i<k;i++)
	{
	   cin>>girl>>boy;
	   p[girl].push_back(boy);//将每一个girl对应的boy动态加入
	
	}

	 memset(link,-1,sizeof(link));//设开始没有男孩子有伴侣


	 //遍历女孩子
	
	 for(int i=1;i<=m;i++)
	 {
		memset(vis,false,sizeof(vis));//将男孩伴侣状态设为false,增加男女接触机会
	    if(solve(i))判断这个女孩子是否有合适的伴侣
			ans++;
	 }
	 cout<<ans<<endl;

	}
    return 0;
}

K - 汉诺塔III

 HDU - 2064 

约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。
现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。
Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边?

Input

包含多组数据,每次输入一个N值(1<=N=35)。

Output

对于每组数据,输出移动最小的次数。

Sample

InputcopyOutputcopy
 
1
3
12
 
2
26
531440

总结:找规律

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<sstream>
using namespace std;
int main()
{  long long a[1000],n;
a[0]=2;
a[1]=8;
a[2]=26;
for(int i=3;i<36;i++)
   a[i]=3*a[i-1]+2;
while(cin>>n){
printf("%lld\n",a[n-1]);
}
return 0;
}

L - "红色病毒"问题

 HDU - 2065 

医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶,腺嘧啶均是成对出现的。
现在有一长度为N的字符串,满足一下条件:
(1) 字符串仅由A,B,C,D四个字母组成;
(2) A出现偶数次(也可以不出现);
(3) C出现偶数次(也可以不出现);
计算满足条件的字符串个数.
当N=2时,所有满足条件的字符串有如下6个:BB,BD,DB,DD,AA,CC.
由于这个数据肯能非常庞大,你只要给出最后两位数字即可.

Input

每组输入的第一行是一个整数T,表示测试实例的个数,下面是T行数据,每行一个整数N(1<=N<2^64),当T=0时结束.

Output

对于每个测试实例,输出字符串个数的最后两位,每组输出后跟一个空行.

Sample

InputcopyOutputcopy
 
4
1
4
20
11
3
14
24
6
0
Case 1: 2
Case 2: 72
Case 3: 32
Case 4: 0

Case 1: 56
Case 2: 72
Case 3: 56

总结:第几项为(pow(4,n-1)+pow(2,n-1))%100,但是数据很大,所以采用快速幂;

#include<iostream>
#include<string>
#include<stdlib.h>
#include<cstdio>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<vector>
typedef long long ll;
using namespace std;
ll solve(ll a,ll b)
{
	ll re=1;
	while(b)
	{
    if(b%2)//不等于0就要多乘以a
	 re=re*a%100;//不能re*=a%100;
	 a=a*a%100;
	 b/=2;
	}
return re;
}
int main()
{
	int n;
	while(~scanf("%d",&n)&&n)
	{
		
	  for(int i=1;i<=n;i++)
	  {
	    ll t;
	   scanf("%lld",&t);
	   printf("Case %d: %lld\n",i,(solve(4,t-1)+solve(2,t-1))%100);//找规律,数学要学好
	  
	  }
	
	cout<<endl;
	}
	return 0;
}

M - 一个人的旅行

 HDU - 2066 (待补)

N - 小兔的棋盘

 HDU - 2067 

小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!

Input

每次输入一个数n(1<=n<=35),当n等于-1时结束输入。

Output

对于每个输入数据输出路径数,具体格式看Sample。

Sample

InputcopyOutputcopy
 
1
3
12
-1
 
1 1 2
2 3 10
3 12 416024

总结:看似很难,其实就是卡特兰数的应用,记住a[0]=1,a[1]=1,a[n]=a[0]*a[n-1]+a[1]*a[n-2]....+a[n-1]*a[0];还可以应用在stack的出栈入栈的数量计算.

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
typedef long long ll;
ll a[40];
using namespace std;
void dfs()
{
a[0]=1,a[1]=1;
ll sum;
for(int i=2;i<=35;i++)
{
	sum=0;
  for(int j=0;j<i;j++){
    sum+=a[j]*a[i-1-j];//卡特兰数的推导公式,a[n]=a[0]*a[n-1]+a[1]*a[n-2]....a[n-1]*a[0];
	}
	a[i]=sum;
}
}
int main()
{ 
memset(a,0,sizeof(a));
dfs();
int n,t=0;
while(cin>>n)
{   t++;
	if(n==-1)
	break;
	cout<<t<<" "<<n<<" "<<a[n]*2<<endl;//因为可以走上面,也可以走下面,所以要*2
 
}
	
return 0;
} 

O - RPG的错排

 HDU - 2068 

今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁。RPG给他机会让他猜猜,第一次猜:R是公主,P是草儿,G是月野兔;第二次猜:R是草儿,P是月野兔,G是公主;第三次猜:R是草儿,P是公主,G是月野兔;......可怜的野骆驼第六次终于把RPG分清楚了。由于RPG的带动,做ACM的女生越来越多,我们的野骆驼想都知道她们,可现在有N多人,他要猜的次数可就多了,为了不为难野骆驼,女生们只要求他答对一半或以上就算过关,请问有多少组答案能使他顺利过关。

Input

输入的数据里有多个case,每个case包括一个n,代表有几个女生,(n<=25), n = 0输入结束。

Output

1
1

Sample

InputcopyOutputcopy
 
1
2
0
 
1
1

总结:错排的应用,a[0]=0,a[1]=0,a[2]=1,a[3]=2,a[4]=9,a[n]=(n-1)*(a[n-1]+a[n-2]);

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
typedef long long ll;
long long a[40];

using namespace std;
void def()//求错排
{
a[0]=0,a[1]=0,a[2]=1;
	for(int i=3;i<=25;i++)
	{a[i]=(i-1)*(a[i-1]+a[i-2]);}
}
int main()
{  
	def();
	int n;
   long long s=0,s1=1,s2=1,s3=1;
	while(cin>>n)
	{
		
	if(n==0)
		break;
	if(n==1||n==2)//当n==1和2时结果都是1
	{cout<<1<<endl;continue;}
	  s=0;
	 for(ll i=2;i<=n/2;i++)//求阶乘
	 {
		 s2=1,s3=1;
	   for(ll j=n;j>=n-i+1;j--)
	   {
	     s2*=j;
		
	   
	   }
	   for(ll j=1;j<=i;j++)
	   { s3*=j;
	   
	   
	   }
	    
	   s+=a[i]*(s2/s3);//错排*(从n个里面抽i个数的概率)
	 }
	 printf("%lld\n",s+1);//
	}
	
return 0;
} 

P - Coin Change

 HDU - 2069 

Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money.

For example, if we have 11 cents, then we can make changes with one 10-cent coin and one 1-cent coin, or two 5-cent coins and one 1-cent coin, or one 5-cent coin and six 1-cent coins, or eleven 1-cent coins. So there are four ways of making changes for 11 cents with the above coins. Note that we count that there is one way of making change for zero cent.

Write a program to find the total number of different ways of making changes for any amount of money in cents. Your program should be able to handle up to 100 coins.

Input

The input file contains any number of lines, each one consisting of a number ( ≤250 ) for the amount of money in cents.

Output

For each input line, output a line containing the number of different ways of making changes with the above 5 types of coins.

Sample

InputcopyOutputcopy
 
11 
26 
 
4 
13 

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
ll a[100],f[300];
int b[6]={0,1,5,10,25,50};
ll c1[300][120],c2[300][120];
int main()
{

	 memset(f,0,sizeof(f));
	 memset(c1,0,sizeof(c1));
	 c1[0][0]=1;
	 
	 for(int i=1;i<=5;i++)//5种面值
	 {
	  memset(c2,0,sizeof(c2));//初始化c2
	  for(int j=0;j<=250;j++)//钱数最大为250,依次遍历
	  {
	  for(int k=0;j+k*b[i]<=250;k++)//母函数
	  {
		  for(int p=0;p+k<=100;p++){//p+k是换取的硬币数不超过100
			  c2[j+k*b[i]][p+k]+=c1[j][p];}//第一个表示价值,第二个表示硬币个数
	  }
	  }
	memcpy(c1,c2,sizeof(c2));
	 }
	  for(int i=1;i<=250;i++)
    {
        for(int j=0;j<=100;j++)
        {
            f[i]+=c1[i][j];//将价值相同换取不同硬币的个数相加
        }
    }
    f[0]=1;//0价值只能换取0个硬币
	
 int n;
 while(cin>>n)//防止时间超限
 {
  cout<<f[n]<<endl;//输出价值为n时的种数
 }
return 0;
} 

Q - Fibbonacci Number

 HDU - 2070

Your objective for this question is to develop a program which will generate a fibbonacci number. The fibbonacci function is defined as such:

f(0) = 0
f(1) = 1
f(n) = f(n-1) + f(n-2)

Your program should be able to handle values of n in the range 0 to 50.

Input

Each test case consists of one integer n in a single line where 0≤n≤50. The input is terminated by -1.

Output

Print out the answer in a single line for each test case.

Sample

InputcopyOutputcopy
 
3 
4 
5 
-1 
 
2 
3 
5
you can use 64bit integer: __int64

Hint

Note:

总结:输入-1,结束程序

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<sstream>
using namespace std;
int main()
{  
	long long a[60];
	a[0]=0;
	a[1]=1;
	for(int i=2;i<=50;i++)
		a[i]=a[i-1]+a[i-2];
	int n;
	while(cin>>n)
	{
		if(n==-1)
			{
		      break;
		}
	printf("%lld\n",a[n]);
	
	}
system("pause");
return 0;
}

R - Max Num

 HDU - 2071 

There are some students in a class, Can you help teacher find the highest student .

Input

There are some cases. The first line contains an integer t, indicate the cases; Each case have an integer n ( 1 ≤ n ≤ 100 ) , followed n students’ height.

Output

For each case output the highest height, the height to two decimal plases;

Sample

InputcopyOutputcopy
 
2
3 170.00 165.00 180.00
4 165.00 182.00 172.00 160.00
 
180.00
182.00

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<sstream>
using namespace std;
int main()
{  
	int n;
	while(cin>>n)
	{
	  int k;
	  double a[100000];
	  for(int i=0;i<n;i++)
	  {
	   cin>>k;
	   double s=0;
	   for(int j=0;j<k;j++)
	   {
	   cin>>a[j];
	   }
	   s=*max_element(a,a+k);//求出数组最大值
	   printf("%.2f\n",s);
	  }
	
	
	
	}
	

return 0;
}

S - 单词数

 HDU - 2072 

lily的好朋友xiaoou333最近很空,他想了一件没有什么意义的事情,就是统计一篇文章里不同单词的总数。下面你的任务是帮助xiaoou333解决这个问题。

Input

有多组数据,每组一行,每组就是一篇小文章。每篇小文章都是由小写字母和空格组成,没有标点符号,遇到#时表示输入结束。

Output

每组只输出一个整数,其单独成行,该整数代表一篇文章里不同单词的总数。

Sample

InputcopyOutputcopy
 
you are my friend
#
 
4

#include <iostream>  
#include <set>  
#include <string>  
#include <sstream>
 
using namespace std;  
 
int main() {  
	string t;  
	while(getline(cin,t) && t != "#"){  
		istringstream stream(t);  
		string word;  
		set<string> map;  
		while(stream >>word){  //将word一个一个的输入map中
			map.insert(word);  
		}  
		cout <<map.size() <<endl;  
	}  
	return 0;  
}

T - 无限的路

 HDU - 2073 

甜甜从小就喜欢画图画,最近他买了一支智能画笔,由于刚刚接触,所以甜甜只会用它来画直线,于是他就在平面直角坐标系中画出如下的图形:
 

 甜甜的好朋友蜜蜜发现上面的图还是有点规则的,于是他问甜甜:在你画的图中,我给你两个点,请你算一算连接两点的折线长度(即沿折线走的路线长度)吧。

Input

第一个数是正整数N(≤100)。代表数据的组数。
每组数据由四个非负整数组成x1,y1,x2,y2;所有的数都不会大于100。

Output

对于每组数据,输出两点(x1,y1),(x2,y2)之间的折线距离。注意输出结果精确到小数点后3位。

InputcopyOutputcopy
 
5
0 0 0 1
0 0 1 0
2 3 3 1
99 99 9 9
5 5 5 5
 
1.000
2.414
10.646
54985.047
0.000

总结:找规律,如果两个点x+y==x1+y1,则两个点在同一直线上,假如(1,1)到(3,2)则我们就是要求,(2,0)~(0,3)之间的距离+(0,3)~(3,0)的距离+(3,0)~(0,4)的距离+(0,4)~(3,2)的距离。

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<sstream>
using namespace std;
int main()
{
	int n;
	while(cin>>n)
	{
	int x1,x2,y1,y2;
	
	for(int i=0;i<n;i++)
	{
		double s=0;
	  cin>>x1>>y1>>x2>>y2;
	  int x11,x12,y11,t12,s11,s12;
		s11=x1+y1;
		s12=x2+y2;
		if(s11>s12)//大的坐标放后面
		{
		  int t1=x1;
		  int t11=y1;
		  x1=x2;
		  y1=y2;
          x2=t1;
		  y2=t11;
		
		}
	   if(s11==s12)//同一直线上
	   {
	   s=sqrt(pow(x1-x2,2.0)+pow(y1-y2,2.0));
	   }
	   else
	   {
		  
	     for(int j=x1+y1;j<x2+y2;j++)
		 {
			 
			 if(j>x1+y1&&j<x2+y2)//有规律可得,可以自己算一两个列子即可知道
				 {s+=sqrt(pow(j,2.0)*2.0);
			      s+=sqrt(pow(j,2.0)*1.0+pow(j+1,2.0)*1.0);
			   
			 
			 }
			 else
				 {s+=sqrt(pow(j,2.0)*1.0+pow(j+1,2.0)*1.0);
			      
			 
			 }
		
		 }

		 s+=sqrt(pow(y1,2.0)*1.0+pow(y1,2.0)*1.0)+sqrt(pow(x2,2.0)*1.0+pow(x2,2.0)*1.0);//将相邻的坐标提取出来算,有规律的放在前面算.
	   
	   }
	   printf("%.3f\n",s);
	}
	
	
	
	}
return 0;
}

U - 叠筐

 HDU - 2074 

(待补)

V - A|B?

 HDU - 2075 

正整数A是否能被正整数B整除,不知道为什么xhd会研究这个问题,来帮帮他吧。

Input

输入数据的第一行是一个数据T,表示有T组数据。
每组数据有两个正整数A和B(A,B<10^9)。

Output

对于每组输入数据,输出"YES"表示可以被整除,"NO"表示不能被整除。

Sample

InputcopyOutputcopy
 
2
4 2 
5 3 
 
YES 
NO 

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<sstream>
using namespace std;
int main()
{  
	int t;
	while(cin>>t)
	{
		
	  long int  a,b;
	  for(int i=0;i<t;i++){
	  cin>>a>>b;
	 for(int i=1;i<10000;i++)
		 {
			 if(a<1000)//a先减去n个b,足够小之后退出循环
				 break;
			 a-=b*i;
	 }
	  if(a%b==0)//判断是否可以除以b
		  cout<<"YES"<<endl;
	  else
	       cout<<"NO"<<endl;
	  }
	
	}
return 0;
}

W - 夹角有多大(题目已修改,注意读题)

 HDU - 2076 

时间过的好快,一个学期就这么的过去了,xhd在傻傻的看着表,出于对数据的渴望,突然他想知道这个表的时针和分针的夹角是多少。现在xhd知道的只有时间,请你帮他算出这个夹角。

注:夹角的范围[0,180],时针和分针的转动是连续而不是离散的。

Input

输入数据的第一行是一个数据T,表示有T组数据。
每组数据有三个整数h(0 <= h < 24),m(0 <= m < 60),s(0 <= s < 60)分别表示时、分、秒。

Output

对于每组输入数据,输出夹角的大小的整数部分。

Sample

InputcopyOutputcopy
 
2
8 3 17 
5 13 30 
 
138 
75 

#include<iostream>
#include<string>
#include<stdlib.h>
#include<cstdio>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<vector>
typedef long long ll;
using namespace std;

int main()
{
	double h,m,s;
	int t;
	while(cin>>t)
	{ 
		for(int i=0;i<t;i++){
		
	 cin>>h>>m>>s;
	 double h1=0,m1=0;
	 if(h>=12)//一个时钟一圈为12小时
		 h-=12;
	 h1=(h+m/60+s/3600)*30;//算时针一共转了多少度数
	m1=(m+s/60)*6;//分针一共转了多少度数
	h1=abs(h1-m1);//两者之差的绝对值
	
	if(h1>180)//大于180,则取补角
		h1=360-h1;
	h1=h1-0.5;//取整
	if(h1<=0)
		printf("0\n");
	else
	 printf("%.f\n",h1);
	}
	}
	return 0;
}

X - 汉诺塔IV

 HDU - 2077 

还记得汉诺塔III吗?他的规则是这样的:不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到小盘的上面。xhd在想如果我们允许最大的盘子放到最上面会怎么样呢?(只允许最大的放在最上面)当然最后需要的结果是盘子从小到大排在最右边。

Input

输入数据的第一行是一个数据T,表示有T组数据。
每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。

Output

对于每组输入数据,最少需要的摆放次数。

Sample

InputcopyOutputcopy
 
2 
1 
10 
 
2 
19684

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
ll a[100];

int main()
{
 a[1]=2,a[2]=4,a[3]=10;\\自己算前面几个
 for(int i=4;i<=20;i++)\\然后找规律
	 a[i]=a[i-1]*3-2;
 int n;
 while(cin>>n)
 {
 for(int i=0;i<n;i++){
 int t;
 cin>>t;
 cout<<a[t]<<endl;
 }
 }
return 0;
} 

Y - 复习时间

 HDU - 2078 

为了能过个好年,xhd开始复习了,于是每天晚上背着书往教室跑。xhd复习有个习惯,在复习完一门课后,他总是挑一门更简单的课进行复习,而他复习这门课的效率为两门课的难度差的平方,而复习第一门课的效率为100和这门课的难度差的平方。xhd这学期选了n门课,但是一晚上他最多只能复习m门课,请问他一晚上复习的最高效率值是多少?

Input

输入数据的第一行是一个数据T,表示有T组数据。
每组数据的第一行是两个整数n(1 <= n <= 40),m(1 <= m <= n)。
接着有n行,每行有一个正整数a(1 <= a <= 100),表示这门课的难度值。

Output

对于每组输入数据,输出一个整数,表示最高效率值。

Sample

InputcopyOutputcopy
2
2 2
52
25
12 5
89
64
6
43
56
72
92
23
20
22
37
31
5625
8836 

总结:看似比较复杂,实则找规律即可,就是(100-min)*(100-min)

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<sstream>
using namespace std;
int main()
{
	int t,a[10000];
	while(cin>>t)
	 {
	for(int j=0;j<t;j++){
		 int n,m;
         cin>>n>>m;
	for(int i=0;i<n;i++)
	{
	  cin>>a[i];
	}
	int min=100-*min_element(a,a+n);
	cout<<min*min<<endl;
	}
	}
return 0;
}

Z - 选课时间

 HDU - 2079 

又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合。你来帮帮他吧。(xhd认为一样学分的课没区别)

Input

输入数据的第一行是一个数据T,表示有T组数据。
每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。
接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。

Output

对于每组输入数据,输出一个整数,表示学n个学分的组合数。

Sample

InputcopyOutputcopy
2
2 2
1 2
2 1
40 8
1 1
2 2
3 2
4 2
5 8
6 9
7 6
8 8
2
445

总结:和之前那个硬币问题差不多,母函数的应用

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstdlib>
int v1[20],n2[20];
int c1[50],c2[50];
using namespace std;
int main()
{ 
int t;
cin>>t;
while(t--)
{
  memset(v1,0,sizeof(v1));
  memset(n2,0,sizeof(n2));
	int n,k;
	cin>>n>>k;
	
	for(int i=1;i<=k;i++)
	{
	 cin>>v1[i]>>n2[i];
	 
	}
	memset(c1,0,sizeof(c1));
	c1[0]=1;
	
   for(int i=1;i<=k;i++)\\i种学分
   {
	   
     memset(c2,0,sizeof(c2));
	 for(int j=0;j<=n2[i]&&j*v1[i]<=n;j++)\\母函数
	 {
	  for(int k1=0;k1+j*v1[i]<=n;k1++)
	  {
	     c2[k1+j*v1[i]]+=c1[k1];
	  
	  }
	 
	 }
   memcpy(c1,c2,sizeof(c1));\\将c2的值全部赋给c1
   }
  
  printf("%d\n",c2[n]);
}

return 0;
} 

经典语录:长恨复长恨,裁作短歌行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会敲代码的破茧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值