HDU 2061-2080

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

题目集合:http://acm.hdu.edu.cn/listproblem.php?vol=11
2061 Treasure the new start, freshmen!

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

int t,n;
double ans, crd, sco, c_sum, cs_sum;
char s[40];
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d", &n);
		bool flat = 1;
		c_sum=0, cs_sum=0;
		fo(i, 1, n){
			scanf("%s%lf%lf", s, &crd, &sco);
			if(sco<60) flat = 0;
			c_sum += crd;
			cs_sum += crd*sco;
		}
		ans = cs_sum/c_sum;
		if(t>=1 && !flat) printf("Sorry!\n\n");
		else if(!flat)   printf("Sorry!\n");
		else if(t>=1) printf("%.2f\n\n", ans);
		else    printf("%.2f\n", ans);
	}
	return 0;
}

2062 Subset sequence
/* 找规律,找方程 */
{1}
{1,2}
{1,2,3}
{1,3}
{1,3,2}

{2}
{2,1}
{2,1,3}
{2,3}
{2,3,1}

{3}
{3,1}
{3,1,2}
{3,2}
{3,2,1}

这到题的集合排序是这样子的 字典排序 头大则大 头小则小 不优先考虑长度

f(n) 表示按字典排序的集合总数 g(n) 表示每个小组的集合数量
f(n) = (f(n-1)+1) * n
g(n) = f(n)/n
= f(n-1)+1
g(n-1) = f(n-1)/(n-1)
g(n) = g(n-1)*(n-1) + 1

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n, m, g[22], t, a[22];
void init(){
	// 数量为n的分组长度表
	g[1] = 1;
	for(int i=2; i<=21; ++i){
		g[i] = (g[i-1]) * (i-1) + 1;
	}
}
int main(){
	init();
	while(scanf("%lld%lld", &n, &m)!=EOF){
		for(int i=1; i<=20; i++) a[i] = i;
		while(n){
			t = (m-1) / g[n] + 1; // 在n个数的字典集合中,m在第t组 
			printf("%d", a[t]); 
			for(int i=t; i<=20; i++) a[i] = a[i+1]; // 比输出数字大的要左移一位, 比如,如果现在是第2组,那么下该组下的第2组就是3,第3组就是4 
			m -= (t-1) * g[n] + 1; // 需要减去前面的组数量以及头部空集,得到在新的组里是第几个数 
			if(m<=0) { printf("\n");break; }
			else       printf(" ");
			--n; // 集合规模减1,问题规模缩小 
		}
	}
	return 0;
} 

2063 过山车
二分图 最大匹配问题

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; ++i) 
#define ll long long
using namespace std;
int k, m, n, ok[1001][1001], vis[1001], cx[1001], cy[1001];

int dfs(int u){ // 从女生出发,扩充路径 
	fo(v,1,n){
		if(ok[u][v] && !vis[v]){
			vis[v] = 1;
			if(cy[v]==-1 || dfs(cy[v])){
				cy[v] = u; cx[u] = v;
				return 1;
			}
		}
	} 
	return 0;
}
// 打印匹配结果 
void PP(){
	fo(v,1,m){
		if(cx[v]!=-1) printf("[%d, %d]\n", v,cx[v]);
	}
} 
ll maxmatch(){
	ll ans = 0;
	fo(u,1,m){ // 起点是女生,故最多有女生数量的路径数 
		memset(vis,0,sizeof(vis));
		ans += dfs(u);
	}
	//PP();
	return ans;
}
int main(){
	scanf("%d", &k);
	while(k){
		scanf("%d%d",&m,&n);
		memset(ok,0,sizeof(ok));
		memset(cx,-1,sizeof(cx));
		memset(cy,-1,sizeof(cy));
		int t1,t2;
		fo(i,1,k){
			scanf("%d%d",&t1,&t2);
			ok[t1][t2] = 1; // 女到男 
		}
		printf("%lld\n",maxmatch());
		scanf("%d", &k);
	}
	return 0;
}

2064 汉诺塔III
/*
f(n) 表示 从 a 到 c 的总数
f(n-1) 已求
那么f(n)则需要 n-1 个从a移动到c
第n个从a到b n-1 个又从c到a
第n个从b到c n-1 个又从a到c
共 2 + 3f(n-1) 次
故f(n) = 3f(n-1) + 2
推导公式:
f(n)+1 = 3
(f(n-1)+1)
又首项 f(1) + 1 = 3
故f(n)+1 是以3为首项 公比为3的等比数列
故 f(n)+1 = 3^n
f(n) = 3^n -1
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll m_pow(ll x, ll n){
	ll res = 1;
	while(n){
		if(n&1) res *= x;
		x *= x;
		n >>= 1;
	}
	return res;
}
int main(){
	int n;
	while(scanf("%d",&n)!=EOF) printf("%lld\n", m_pow(3,n)-1);
}

2065 "红色病毒"问题 :https://blog.csdn.net/weixin_39778570/article/details/822561284
2066 一个人的旅行

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

const int INF = 0x3f3f3f3f;
const int N = 1005;
typedef pair<int, int> P;

struct edge{
	int to, cost;
};
int V = 1000; // 顶点数 
vector<edge> G[N];
int d[N];
void dijkstra(int s){
	priority_queue< P, vector<P>, greater<P> > que;
	fill(d, d+V+2, INF);
	d[s] = 0;
	que.push(P(0,s));
	while(!que.empty()){
		P p = que.top();
		que.pop();
		int v = p.second;
		if(d[v] < p.first) continue; //到v点的距离如果已经被更新 这无须执行以下操作
		for(auto e : G[v]){
			if(d[e.to] > d[v]+e.cost){
				d[e.to] = d[v] + e.cost;
				que.push(P(d[e.to], e.to));
			}
		}		
	}
}
int T,S,D;
int main(){
	int from, to, cost;
	while(scanf("%d%d%d", &T,&S,&D) != EOF){
		for(int i=0; i<N; i++) G[i].clear();
		fo(i, 1, T){
			scanf("%d%d%d",&from,&to,&cost);
			edge var;
			var.to = to; var.cost = cost;
			G[from].push_back(var);
			var.to = from; var.cost = cost;
			G[to].push_back(var);
		}
		fo(i, 1, S){ // 多个地点问题 
			scanf("%d", &to);
			edge var;
			var.to = to; var.cost = 0;
			G[0].push_back(var);
		}
		dijkstra(0);
		int ans = INF;
		fo(i,1,D){
			scanf("%d", &to);
			if(d[to]<ans) ans = d[to];
		}
		printf("%d\n", ans);
	} 
	
	return 0;
}

2067 小兔的棋盘
/卡塔兰数,大数用java做/

C(2n , n)/( n+1 )
kf[i] = kf[i-1]*1.0/(i+1)*(4*i-2);	
这条公数用来做大数的 
Catalan[i] += Catalan[j] * Catalan[i - 1 - j];
小于35的数据 
/*dp做法*/
#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;
ll dp[40][40];
void init(){
	// 初始化第0行为1
	fo(j, 0, 35) dp[0][j] = 1;
	fo(j, 1, 35){ // 列 
		fo(i, 1, j){ // 行 
			if(i==j) dp[i][j] = dp[i-1][j];
			else dp[i][j] = dp[i-1][j] + dp[i][j-1];
		//	printf("%d %d %lld\n", i, j, dp[i][j]);
		}
		printf("%lld\n",dp[j][j]);
	}
}
int main(){
	init();
	int cnt=0;
	while(scanf("%d", &n)&&n!=-1){
		printf("%d %d %I64d\n", ++cnt, n, dp[n][n]*2);
	}
}
import java.math.BigInteger;
import java.util.Scanner;

public class 卡塔兰数 {
	static BigInteger[] kf = new BigInteger[40];
	static void init() {
		kf[1] = new BigInteger("1");
		BigInteger one = new BigInteger("1");
		BigInteger two = new BigInteger("2");
		BigInteger four = new BigInteger("4");
		for(int i=2; i<=35; ++i) {
			String str = String.valueOf(i);
			BigInteger n = new BigInteger(str);
			kf[i] = (n.multiply(four).subtract(two)).multiply(kf[i-1]).divide(n.add(one));
		}
		for(int i=1; i<=35; i++) kf[i] = kf[i].multiply(two);
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int cnt = 0;
		init();
		while(sc.hasNext()) {
			int n = sc.nextInt();
			if(n==-1)break;
			System.out.println(++cnt+" "+n+" "+kf[n].toString());
		}
	}
}

2068 RPG的错排
组合 + 错排

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

ll dd[30];
ll c[30][30];
void CC(){
	c[0][0] = 1;
	fo(i, 1, 25){
		fo(j, 0, i){
			if(j==0 || i==j) c[i][j] = 1;
			else c[i][j] = c[i-1][j] + c[i-1][j-1];
		//	printf("%lld\n",c[i][j]);
		}
	}
}
void init(){
	dd[0]=1, dd[1] = 0,dd[2] = 1; // dd[0]要设置成1因为下面要乘到 
	fo(i,3,25) dd[i] = (i-1)*(dd[i-1]+dd[i-2]);
//	fo(i,1,25) printf("%I64d\n", dd[i]);  这里其实会溢出,但还AC了。。。 
}
int main(){
	init();
	CC();
	int n;
	while(scanf("%d", &n)&&n!=0){
		int mid = n >> 1; // 小于等于一半人 
		ll ans = 0;
		fo(k,0,mid){
		//	printf("%d\n", k);
			ans += c[n][k]*dd[k];
		}
		printf("%lld\n", ans);
	}
	return 0;
}

2069 Coin Change
硬币组合问题 dp

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;
const int N = 300;
ll dp[300][105];
ll ans [300];
void init(){
	dp[0][0] = 1;
	int coins[5] = {50,25,10,5,1};
	fo(k, 0, 4){           // 第几个硬币 
		fo(i, 1, 250){     // 钱数 
			fo(j, 1, min(100,i)){ // 硬币数,银币数不会大于钱数,最多100个硬币
				if(i>=coins[k]) dp[i][j] += dp[i-coins[k]][j-1];
			}
		}
	}
	ans[0] = 1; 
	fo(i,1,250){
		fo(j,0,min(100,i)) ans[i] += dp[i][j];
	}
} 
int main(){
	init();
	int n;
	while(scanf("%d", &n)!=EOF){
		printf("%lld\n", ans[n]); 
	}
	return 0;
}

2070 Fibbonacci Number

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

ll fb[51];
void init(){
	fb[0] = 0; fb[1] = 1;
	fo(i,2,50){
		fb[i] = fb[i-1] + fb[i-2];
	//	printf("%lld\n", fb[i]);
	}
}

int main(){
	init();
	int n;
	while(scanf("%d",&n) && n!=-1) printf("%lld\n", fb[n]);
	return 0;
} 

2071 Max Num

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;
int t,n;
int main(){
	scanf("%d",&t);
	while(t--){
		double a,max = 0.0;
		scanf("%d", &n);
		fo(i,1,n){
			scanf("%lf", &a);
			if(a>max)max=a;
		}
		printf("%.2f\n",max);
	}
	return 0;
}

2072 单词数

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

map<string,int> mp;
int main(){
	string str,st;
	while(getline(cin,str)&&str!="#"){
		mp.clear();
		stringstream ss(str);
		while(ss>>st) mp[st]++;
		printf("%d\n", mp.size()); 
	}
	
	return 0;
}

2073 无限的路
/注意数组开大点! 9999这个点要在线上,所以要开198至少*/

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

double d[100000],ans;
double dd[250][250];
void init(){
	d[0] = 0.0, d[1] = 1.0;
	dd[0][0] = 0, dd[0][1] = 1.0;
	double m = sqrt(2);
	int now = 2, k;
	fo(i,1,200){
		k = i;
		fo(j,1,i){
			d[now] = d[now-1] + m;
			dd[j][--k] = d[now];
//			cout << j << "  " << k <<" "<< dd[j][k] << endl;
			now++;
		}
		d[now] = d[now-1] + sqrt(i*i+(i+1)*(i+1)); // 注意啦,这里是从一排过度到另一排的斜线
		dd[0][i+1] = d[now];
//		cout << 0 << "  " << i+1 << " " <<dd[0][i+1] << endl;
		now++;
	} 
}
int n,x1,y1,x2,y2;
int main(){
	init();
	scanf("%d", &n);
	while(n--){
		scanf("%d%d%d%d", &x1,&y1,&x2,&y2);
		ans = abs(dd[x1][y1]-dd[x2][y2]);
		printf("%.3f\n", ans);
	}
	return 0;
} 

2074 叠筐

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

void PP(int n, char a, char b){
	if(n==1){printf("%c\n", a);return;}
	memset(s,0,sizeof(s));
	int mid = n/2;
	s[mid][mid] = a;
	int p = mid-1;
	int q = mid+1;
	char c = a;
	while(p>=0){
		if(c==a)c=b;else c=a;
		s[mid][p--] = s[mid][q++] = c;
	}	
//	printf("%s\n", s[mid]);
	int k = 1;
	c = a;
	for(int i=mid-1; i>=0; --i){
		strcpy(s[i], s[mid]);
		p = mid-1;
		q = mid+1;
		if(c==a)c=b;else c=a;
		s[i][mid]=c;
		fo(j,1,k){
			s[i][p--] = s[i][q++] = c;
		}	
		k+=1;	
	//	printf("%s\n", s[i]);
	}
	printf(" ");
	fo(i,1,n-2) printf("%c",s[0][i]);
	printf(" \n");
	fo(i,1,mid) printf("%s\n",s[i]);
	for(int i=mid-1; i>0; --i)printf("%s\n",s[i]);
	printf(" ");
	fo(i,1,n-2) printf("%c",s[0][i]);
	printf(" \n");
}
int main(){ 
//	PP(11,'B','A');
//	PP(5,'@','W');
	int n;
	char a, b;
	int flat = 0;
	while(~scanf("%d %c %c",&n,&a,&b)){
		if(flat) printf("\n");
		else flat=1;
		PP(n,a,b);
	}	 
	return 0;
}

2075 A|B?

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll T, a, b;
int main(){
	cin >> T; 
	while(T--){
		cin >> a >> b;
		if(a%b==0) puts("YES");
		else puts("NO");	 
	}
	return 0;
}

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

#include<bits/stdc++.h>
#define ll lnog long
#define fo(i, j ,n) for(int i=j; i<=n; ++i)
using namespace std;
int T, h, m, s;
int ans;
int main(){
	scanf("%d", &T); 
	while(T--){
		scanf("%d%d%d", &h,&m,&s);
		if(h>=12) h-=12; // 注意不是24小数制的哈 
		double m1 = m + 1.0*s / 60;
		double t1 = h*5 + m1/12;
		double d = abs(t1-m1);
		double dd = min(d, 60-d);
		ans = dd*6/1;
		printf("%d\n", ans);
	} 
	return 0;
}

2077 汉诺塔IV
n-1个到第二个柱子,n(最大)个到第2个柱子再到第3个柱子,n-1和从第二个柱子到第三个柱子
f(n) = 3^n-1 -1 + 2 = 3^n-1 + 1

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

ll pow_mod(ll x, ll n){
	ll res = 1;
	while(n){
		if(n&1) res *= x;
		x *= x;
		n >>= 1;
	}
//	cout << res << endl;
	return res;
}
int T,n;
ll ans;
int main(){
	scanf("%d", &T);
	while(T--){
		scanf("%d", &n);
		ans = pow_mod(3,n-1) + 1;
		printf("%I64d\n", ans);
	} 
	return 0;
} 

2078 复习时间

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

using namespace std;
int t,a[50],ans;
int main(){
	scanf("%d",&t); 
	while(t--){
		memset(a,0,sizeof(a));
		int n,m;
		scanf("%d %d", &n,&m);
		fo(i,0,n-1) scanf("%d", &a[i]);
		sort(a,a+n);
		ans = (100-a[0])*(100-a[0]);
		printf("%d\n",ans); 
	}
	return 0;
} 

2079 选课时间
/组合问题 母函数模板/
/*
a保存结果,b中间结果
v权值 n1初始数量 n2终止数量
*/

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

int t,n,k,last,last2;
int a[1000],b[1000];
int v[10],n2[10];  // 权值,终止数量 
int main(){
	scanf("%d", &t);
	while(t--){
		scanf("%d%d", &n,&k);
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(v,0,sizeof(v));
		memset(n2,0,sizeof(n2));
		
		fo(i, 0, k-1) scanf("%d %d", &v[i], &n2[i]);
		
		a[0]=1;
		last = 0;
		fo(i,0,k-1){ // 第i个括号 
			last2 = last + n2[i]*v[i];    // 目前最远项 
			memset(b,0,sizeof(int)*(last2+1));
			for(int j=0; j<=n2[i]; j++){	     // 遍历第i个括号的每一项 
				for(int k=0; k<=last; k++){  // 遍历a的每一项 
					b[k+j*v[i]] += a[k];
				}
			}
			memcpy(a,b,sizeof(int)*(last2+1));
			last = last2;
		}
	
		printf("%d\n", a[n]);
	}
	return 0;
}

2080 夹角有多大II

#include<bits/stdc++.h>
#define ll long long
#define PI 3.141592
using namespace std;
int t;
double x1,y1,x2,y2;
double a2, b2, c2, cosC, ans;
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%lf %lf %lf %lf", &x1,&y1,&x2,&y2);
		a2 = x1*x1+y1*y1;
		b2 = x2*x2+y2*y2;
	//	cout<< a2 << "\n" << b2<<endl;
		c2 = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
		cosC = (a2+b2-c2)/(2*sqrt(a2)*sqrt(b2));
	//	cout << cosC << endl;
		ans = acos(cosC)*180/PI;
		printf("%.2f\n",ans);
	}
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值