HDU 2041-2060

ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443

题目集合:http://acm.hdu.edu.cn/listproblem.php?vol=11
2041 超级楼梯
简单的递推注意初始条件

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define P pair<int, int>

int dp[100];
void init(){
	dp[1] = 1; // 刚开始在第一级 
	dp[2] = 1;
	for(int i=3; i<100; i++)
		dp[i] = dp[i-1] + dp[i-2];
	dp[1] = 0;
}
int n, a;
int main(){
	init();
	scanf("%d", &n);
	while(n--){
		scanf("%d",&a); 
		printf("%d\n", dp[a]);
	} 
	return 0;
}

2042 不容易系列之二
/* f(x)在第几个站羊的数量 /
/
f(x) - f(x)/2 + 1 = f(x+1)
f(x) = 2 * (f(x+1) -1) */

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define P pair<int, int>

int dp[50];
void init(){
	dp[0] = 3; // 倒过来计数,终点数量 
	for(int i=1; i<50; i++)
		dp[i] = 2*(dp[i-1]-1); 
}
int n, a;
int main(){
	init();
	scanf("%d", &n);
	while(n--){
		scanf("%d",&a); 
		printf("%d\n", dp[a]);
	} 
	return 0;
}

2043 密码

#include<bits/stdc++.h>
using namespace std;

#define ll long long 
#define P pair<int, int>

bool safety(const char *s){
	int len = strlen(s);
	if(len<8 || len>16) return 0;  // 判断1 
	const char *prt = s;
	bool ok1=0,ok2=0,ok3=0,ok4=0;
	int cnt = 0;
	while(*prt!=0){  // 记得解引用 ,结束符为0 
		if(*prt>='A' && *prt<='Z') {
			if(!ok1) {
				cnt++; 
				ok1 = 1;
			}
		}
		else if(*prt>='a' && *prt<='z') {
			if(!ok2) {
				cnt++; 
				ok2 = 1;
			}
		}
		else if(*prt>='0' && *prt<='9') {
			if(!ok3) {
				cnt++; 
				ok3 = 1;
			}
		}
		else if(*prt=='~' || *prt=='!' || *prt=='@' || *prt=='#' || *prt=='$' || *prt=='%' || *prt=='^') {
			if(!ok4) {
				cnt++; 
				ok4 = 1;
			}
		}	
		if(cnt>=3) return 1;	
		prt++;
	}
	return cnt>=3;
}
int n;
char c[100];
int main(){
	scanf("%d", &n);
	while(n--){
		scanf("%s", c);
		if(safety(c)) printf("YES\n");
		else          printf("NO\n"); 
	}
	return 0;
} 

2044 一只小蜜蜂…

#include<bits/stdc++.h>
using namespace std;

#define ll long long 
#define P pair<int, int>

ll dp[55];  // 注意溢出情况 
void init(){
	dp[1] = 1;
	dp[2] = 2;
	for(int i=3; i<=50; i++){
		dp[i] = dp[i-1]+dp[i-2];
	} 
}
int n,a,b;
int main(){
	init();
	scanf("%d", &n);
	while(n--){
		scanf("%d%d", &a,&b);
		printf("%lld\n", dp[b-a]);
	}
} 

2045 不容易系列之(3)—— LELE的RPG难题
第n-1种颜色如果跟第一种颜色不一样那么第n种只有一种颜色可以选
第n-1种颜色如果跟第一种颜色一样那么n有两种颜色可以选,与第n-2种可以选择的颜色一样

#include<bits/stdc++.h>
using namespace std;

#define ll long long 
#define P pair<int, int>

ll dp[55];  // 注意溢出情况 
void init(){
	dp[1] = 3; dp[2] = 6; dp[3] = 6;
	for(int i=4; i<=50; i++){
		dp[i] = 2*dp[i-2] + dp[i-1];
	} 
}
int n;
int main(){
	init();
	while(scanf("%d",&n) != EOF){
		printf("%lld\n", dp[n]);
	}
	return 0;
}

2046 骨牌铺方格
骨牌的长度只有2,它最多影响的范围是两列,在两列中寻找变化
当n-1列为竖直放置的时候n列只能竖直放置(一种情况)
当n-1列为水平放置的时候n列只能水平放置(一种情况)

#include<bits/stdc++.h>
using namespace std;

#define ll long long

ll dp[55];
void init(){
	dp[1] = 1;
	dp[2] = 2;
	for(int i=3; i<=50; i++)
		dp[i] = dp[i-1] + dp[i-2]; 
}
int n; 
int main(){
	init();
	while(scanf("%d",&n)!=EOF) printf("%lld\n", dp[n]);
	return 0;
}

2047 阿牛的EOF牛肉串
/*
当n-1个为EF时: 此时第n个 的选择为 f(n-2)23
当n-1个为O时 : 第n-1为o的数量为 f(n-1) - f(n-2)*2 即总数量减去EF数量
此时第n个 的选择为 (f(n-1) - f(n-2)2)2
相加化简得 : f(n) = 2
f(n-1) +2
f(n-2)
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll dp[55];
void init(){
	dp[1] = 3; dp[2] = 8;
	for(int i=3; i<=40; i++) dp[i] = 2*dp[i-1] + 2*dp[i-2];
}
int n;
int main(){
	init();
	while(scanf("%d",&n)!=EOF)printf("%lld\n",dp[n]);
	return 0;
}

2048 神、上帝以及老天爷
/*
错排问题:
1)把第n个元素放置第k位 有n-1种放法
2)把第k个元素放在第n位,这是剩下n-2种元素进行错排
不把第k个元素放在第n位,这时有n-1个元素进行错排
元素k不放在第n位,可以直接认为他就是第n位的元素,错排后他就不再第n位了
所以f(n) = (n-1) (f(n-1) + f(n-2))
f(n)表示有n个元素进行错排
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll dp[30];
double gl[30];
void init(){
	dp[1] = 0;
	dp[2] = 1;
	gl[1] = 1;
	gl[2] = 0.5;
	double sum = 2;
	for(int i=3; i<=20; i++){
		dp[i] = (i-1) * (dp[i-2]+dp[i-1]);
		sum *= i;
		gl[i] = dp[i]/sum;
		//printf("%lld %f %f\n", dp[i], sum, gl[i]);		
	}
}	
int n,a;
int main(){
	init();
	scanf("%d", &n);
	while(n--){
		scanf("%d",&a);
		printf("%.2f%%\n", gl[a]*100); // 两个%输出一个% 	
	}
	return 0;
}

2049 不容易系列之(4)——考新郎
组合加错排 小数据

#include<bits/stdc++.h>
#define FOR(i,j,n)for(int i=j; i<=n; ++i)
#define P pair<int,int>
#define ll long long
using namespace std;

ll c[30][30];
void init(){
	FOR(i,0,20) c[i][0] = 1;
	FOR(i,1,20){
		FOR(j,1,i){
			c[i][j] = c[i-1][j] + c[i-1][j-1];
		}
	} 
}
ll dp[30];
void init1(){
	dp[1] = 0; dp[2] = 1;
	FOR(i,3,20) dp[i] = (i-1)*(dp[i-1]+dp[i-2]);
}
int main(){
	init();
	init1();
	int t,a,b;
	scanf("%d", &t);
	while(t--){
		scanf("%d%d", &a,&b);
		printf("%lld\n",c[a][b]*dp[b]);
	}
	return 0;
}

2050 折线分割平面
递推求和
见几何篇

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; i++)
#define ll long long

using namespace std;
int t,m;
int main(){
	scanf("%d", &t);
	while(t--){
		scanf("%d", &m);
		printf("%d\n", 2*m*m-m+1);	
	}
	return 0;
}

2051 Bitset
10转2进制

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; i++)
#define ll long long

using namespace std;
int n;
int a[1000]; 
void solve(ll n){
	int cnt = 0;
	while(n){
		a[++cnt] = n&1; 
		n >>= 1;
	}
	for(int i=cnt; i>=1; i--)printf("%d", a[i]);
	printf("\n");
}
int main(){
	while(scanf("%d",&n)!=EOF){
		solve(n);
	}
	return 0;
}

2052 Picture
绘制矩形

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; i++)
#define ll long long

using namespace std;
int n,m;
void solve(int n, int m){
	printf("%c", '+');
	fo(i,1,n) printf("%c",'-');
	printf("%c\n", '+');
	fo(i,1,m){
		printf("%c",'|');
		fo(i,1,n) printf("%c",' ');
		printf("%c\n",'|');
	}
	printf("%c", '+');
	fo(i,1,n) printf("%c",'-');
	printf("%c\n\n", '+');
} 
int main(){
	while(scanf("%d%d", &n,&m)!=EOF){
		solve(n,m);
	}
}

2053 Switch Game
求约数个数的奇偶问题

#include<bits/stdc++.h>
#define fo(i, j, n) for(int i=j; i<=n; i++)
#define ll long long 
using namespace std;
int n;
int main(){
	while(scanf("%d", &n)!=EOF){
		int k = sqrt(n);
		if(k*k==n)printf("1\n");
		else printf("0\n");
	} 
	return 0;
} 

2054 A == B ?

#include<bits/stdc++.h>
#define fo(i, j, n) for(int i=j; i<=n; ++i)
#define ll long long

using namespace std;
char s1[1000000],s2[1000000];
string getStr(const char *p1){
	string s1;
	const char *ptr1 = p1;
	// 头加正负 
	if(*ptr1!=0 && *ptr1 == '-') {
		s1+="-";
		ptr1++;
	}
	else if(*ptr1!=0 && *ptr1 == '+') {
		s1 += "+";
		ptr1++;
	}
	else if(*ptr1!=0){
		s1 += "+";
	}
	// 去头0
	while(*ptr1!=0 && *ptr1=='0')ptr1++;
	// +0.1的情况 需要补头0 
	if(*ptr1!=0 && *ptr1=='.') s1 += "0";
	// cout << s1 << endl;
	// 小数点 
	while(*ptr1 != 0 && *ptr1!='.') {
		s1 += *ptr1;
		ptr1++;
	}
	
	// 小数点的位置 cout << ptr1-p1 << endl;
	// 去小数点后面的0
	if(*ptr1 != 0 && *ptr1=='.'){
		int st = ptr1-p1+1; // 小数点后第一个位置 
		int j = strlen(p1);
		int i=j-1; // 最终位置 
		for(; p1[i]!='.'&&p1[i]=='0'; --i);
		if(i>st) s1 += ".";
		for(int k=st; k<=i; ++k) s1 += p1[k];
	} 
	return s1;
}
string g1,g2;
int main(){
	while(scanf("%s%s", s1, s2) !=EOF){
		g1 = getStr(s1);
		g2 = getStr(s2);
//		cout<< g1 <<endl;
//		cout<< g2 <<endl;
		if(strcmp(g1.c_str(),g2.c_str()) == 0)printf("YES\n"); // string 比较要变成字符数组 
		else printf("NO\n");
	}
	return 0;
}

2055 An easy problem

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; ++i) 
#define ll long long
using namespace std;

ll t, r, ans;
char c;
ll f(int c){
	if(c>='A' && c<='Z') return c-'A'+1;
	else return -(c-'a'+1);
}
int main(){
	scanf("%lld", &t);
	while(t--){
		scanf("%s%d", &c,&r);	// 注意缓存区 !!!!%s或者getchar()
		ans = r+f(c);
		cout<<ans<<endl;
	}	
	return 0; 
}

2056 Rectangles

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; ++i)
#define ll long long
using namespace std;
typedef struct{
	double x, y;
}NODE;
NODE a, b, c, d;

int main(){
	while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y)!=EOF){
		double x1 = min(a.x,b.x);double y1 = min(a.y,b.y);
		double x2 = max(a.x,b.x);double y2 = max(a.y,b.y);
		double x3 = min(c.x,d.x);double y3 = min(c.y,d.y);
		double x4 = max(c.x,d.x);double y4 = max(c.y,d.y);	
		double X1 = max(x1,x3);  double Y1 = max(y1,y3);
		double X2 = min(x2,x4);  double Y2 = min(y2,y4);
		if(X1<X2 && Y1<Y2) printf("%.2f\n", (X2-X1)*(Y2-Y1));
		else puts("0.00");	
	}	
	return 0;
}

2058 The sum problem
/严格递增区间和问题 使用等差数列求和公式/
/最长长度sqrt(2m)计算*/
/*
1+…+k >= m
k(1+k)/2 >= m
k+k^2 >= 2m
令K^2 = k + k^2 则 K>k (k>=1)
则 1+2+…+K > m
故 最大连续长度不超过 K = sqrt(2m)
*/

#include<bits/stdc++.h>
#define ll long long
ll n, m;
int main(){
	while(scanf("%lld%lld",&n,&m) && (n!=0||m!=0)){
		for(int k=(int)sqrt(2*m); k>=1; k--){ // k长度 
			int a = m/k - (k-1)/2; // 浮点问题,利用等差公式和长度算出a(起点) 
			if(2*k*a+k*(k-1) == 2*m){ // 加一步判读,无除法不丢失精度 
				if(a<=n && a+k-1<=n) printf("[%d,%d]\n",a,a+k-1);
			}
		}
		printf("\n");
	}
	return 0;
} 

2059 龟兔赛跑
这道题目是DP中多阶段决策的典型例题
我们将起点和终点划分到N个加电站中去
这样一共有N+2点,用DP[i]表示到第i个加电站的最小耗费时间
那么在求DP[i]的时候,DP[0]…DP[i-1]已经求得
让j从0遍历到i-1,每一个j表示最后一次充电到i点
那么状态转移方程为
DP[i] = min(DP[j] + t(j, i)) //t(j, i)表示从j充完电一直到i点(中途没有充过电)

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; ++i)
#define ll long long
using namespace std;
const double inf = 0xfffff;

double dp[105];
double L, Time;
int s[105];
int N,C,T,vr,vt1,vt2,len;
int main(){
	while(scanf("%lf",&L)!=EOF){
		scanf("%d%d%d", &N,&C,&T);	
		scanf("%d%d%d", &vr,&vt1,&vt2);
		fo(i,1,N) scanf("%d", &s[i]);
		s[0] = 0; s[N+1] = L; // 把起点和终点设置为加油站 
		dp[0] = 0; // 起点
		fo(i,1,N+1){
			dp[i] = inf;
			fo(j,0,i-1){ // 在第j个站充电,后面不充电 
				len = s[i] - s[j];
				if(len > C) Time = C*1.0/vt1 + (len-C)*1.0/vt2;
				else        Time = len*1.0 / vt1;
				if(j>0) Time += T; // 第一个站不用充电时间
				Time += dp[j];
				dp[i] = min(dp[i],Time); 
			}
		}
		if(dp[N+1] > L*1.0/vr) printf("Good job,rabbit!\n");
		else printf("What a pity rabbit!\n");
	}
	return 0;
} 

2060 Snooker

#include<bits/stdc++.h> 
#define fo(i,j,n) for(int i=j; i<=n; ++i)
using namespace std;
int t,m,p,o;
int main(){
	scanf("%d", &t);
	while(t--){
		scanf("%d%d%d", &m,&p,&o);
		if(m<=6){ // 白球不算,场上已经没有红球了 
			p += (15*m-m*m)/2;
		}else{
			p += (m-6)*8 + 27;
		}
		if(p>=o)puts("Yes");
		else    puts("No");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值