HDU2031-2040题解

本文精选了多项算法竞赛题目,包括进制转换、杨辉三角、A+B问题、A-B问题、快速幂、多边形面积计算、贪心算法、三角形判断及亲和数求解,提供了详细的代码实现与思路解析。

2031 进制转换

任何数制间的转换都可以通过辗转相除法进行,不过要倒排。可以用string,也可以用栈,每次进入一个余数,然后pop即可。

#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
string intRadixChange(int x, int r) {
	string t = "";
	while (x) {
		int temp = x % r;
		t += temp > 9 ? 'A' + temp - 10 : '0' + temp;
		x /= r;
	}
	return t;
}
int main() {
	int n, r;
	while (~scanf("%d%d", &n, &r)) {
		if (n < 0) {
			printf("-");
			n = -n;
		}
		string t = intRadixChange(n, r);
		reverse(t.begin(), t.end());
		cout << t << endl;
	}
	return 0;
} 

2032 杨辉三角

直接填充二维数组。而我在CodeUp上面采取的是两个数组交替的方式。
链接:算法笔记CodeUp第一至第六章刷题记录

#include <cstdio> 
using namespace std;

int main() { 
	long long tri[35][35];
	tri[0][0] = tri[1][0] = tri[1][1] = 1;
	for (int i = 2; i < 35; i++) {
		tri[i][0] = tri[i][i] = 1;
		for (int j = 1; j < i; j++) 
			tri[i][j] = tri[i - 1][j - 1] + tri[i - 1][j];
	}
	int n;
	while (~scanf("%d", &n)) {
	 	for (int i = 0; i < n; i++) {
			for (int j = 0; j <= i - 1; j++) 
				printf("%lld ", tri[i][j]);
			printf("%lld\n", tri[i][i]);
		}
		printf("\n");
	}
	return 0;
}

2033 人见人爱A+B

#include <cstdio>
const int hour = 3600, minu = 60;
int main() {
	int n, ah, am, as, bh, bm, bs;
	scanf("%d", &n);
	while (n--) { //分和秒的取值范围在0~59, 时的取值范围在int内 
		scanf("%d%d%d%d%d%d", &ah, &am, &as, &bh, &bm, &bs);
		int sum = (ah + bh) * hour + (am + bm) * minu + as + bs;
		printf("%d %d %d\n", sum / hour, sum % hour / minu, sum % minu); 
	}
	return 0;
}

2034 人见人爱A-B

使用set,删除A中的同时也在B中的元素。

#include <cstdio>
#include <set>
using namespace std;
typedef set<int>::iterator ST;
int main() {
	int n, m, t;
	while (~scanf("%d%d", &n, &m) && (n || m)) {
		set<int> st;
		for (int i = 0; i < n; i++) {
			scanf("%d", &t);
			st.insert(t);
		}
		for (int i = 0; i < m; i++) {
			scanf("%d", &t); //B集合元素
		    ST it = st.find(t);
			if (it != st.end()) //在A集合中有B集合元素 
			    st.erase(it); //减去B集合元素 
		}
		if (st.size() == 0) printf("NULL\n");
		else { 
			for (ST i = st.begin(); i != st.end(); i++)  
				printf("%d ", *i);  
			printf("\n");
		}
	} 
	return 0;
} 

(快速幂+取余) 2035 人见人爱A^B

每一步对得到的数字%1000。

#include <cstdio>
typedef long long ll; 
ll qpow(ll a, ll b, ll k) { 
	ll ans = 1;
	while (b) {
		if (b & 1) ans = (ans * a) % k;
		b >>= 1; a = (a * a) % k;
	}
	return ans % k;
} 
int main() {
	ll a, b;
	while (~scanf("%lld%lld", &a, &b) && (a || b)) 
		printf("%lld\n", qpow(a, b, 1000));
	return 0;
}

(任意多边形面积-有向面积) 2036 改革春风吹满地

  • Problem Description
    “ 改革春风吹满地,
    不会AC没关系;
    实在不行回老家,
    还有一亩三分地。
    谢谢!(乐队奏乐)”
    话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里雾里,而且,还竟然来这么几句打油诗。
    好呀,老师的责任就是帮你解决问题,既然想种田,那就分你一块。
    这块田位于浙江省温州市苍南县灵溪镇林家铺子村,多边形形状的一块地,原本是linle 的,现在就准备送给你了。不过,任何事情都没有那么简单,你必须首先告诉我这块地到底有多少面积,如果回答正确才能真正得到这块地。
    发愁了吧?就是要让你知道,种地也是需要AC知识的!以后还是好好练吧…

  • Input
    输入数据包含多个测试实例,每个测试实例占一行,每行的开始是一个整数n(3<=n<=100),它表示多边形的边数(当然也是顶点数),然后是按照逆时针顺序给出的n个顶点的坐标(x1, y1, x2, y2… xn, yn),为了简化问题,这里的所有坐标都用整数表示。
    输入数据中所有的整数都在32位整数范围内,n=0表示数据的结束,不做处理。

  • Output
    对于每个测试实例,请输出对应的多边形面积,结果精确到小数点后一位小数。每个实例的输出占一行。

  • Sample Input

    3 0 0 1 0 0 1
    4 1 0 0 1 -1 0 0 -1
    0
    
  • Sample Output

    0.5
    2.0
    

(区间贪心) 2037 今年暑假不AC

贪心思想,优先选择结束时间早的或者是开始时间最晚的

#include <cstdio>
#include <algorithm>
using namespace std;
struct node {
	int s, e;
};
bool cmp(const node &a, const node &b) { //开始时间最晚的排在前面
	if (a.s != b.s) return a.s > b.s; //左端点越大 
	else return a.e < b.e; //左端点相同, 右端点越小 
}
int main() {
	int n;
	while (~scanf("%d", &n) && n) {
		struct node all[110];
		for (int i = 0; i < n; i++) 
			scanf("%d%d", &all[i].s, &all[i].e);
		sort(all, all + n, cmp);
		int lastS = all[0].s, ans = 1;
		for (int i = 1; i < n; i++) {
			if (all[i].e <= lastS) { //在最右边的左端点前面 
				ans++;
				lastS = all[i].s;
			}
		}
		printf("%d\n", ans); 
	}
	return 0;
} 

2038 HDU无此题

2039 三角形

注意:题目中说的是数,而非整数,用int会WA。三边构成三角形的充要条件是较小的两边之和大于第三边

#include <cstdio>
#include <algorithm>
using namespace std;
int main() {
	int n;
	double a[3];
	scanf("%d", &n);
	while (n--) { 
		scanf("%lf%lf%lf", &a[0], &a[1], &a[2]);
		sort(a, a + 3);
		if (a[0] + a[1] > a[2]) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

2040 亲和数

首先知道什么叫做真约数,一个数a能够被不是自身的约数m整除,那么这个约数m就是a的真约数,而a本身不能作为a的真约数。因此,我们计算到a/2就可以找到a的所有真约数。另外,必须两个数中任何一个数都等于另一个数的真约数之和,这两个数才是亲和数。

#include <cstdio>
bool judge(int a, int b) {
	int suma = 0, sumb = 0, ha = a / 2, hb = b / 2; //a和b的真约数之和
	for (int i = 1; i <= ha; i++)  
		if (a % i == 0) suma += i;  
	for (int i = 1; i <= hb; i++)  
		if (b % i == 0) sumb += i; 
	if (suma == b && sumb == a) return true;
	else return false;
}
int main() {
	int m, a, b;
	scanf("%d", &m);
	while (m--) {
        scanf("%d%d", &a, &b);
		if (judge(a, b)) printf("YES\n"); 
		else printf("NO\n");
	}
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

memcpy0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值