ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

6/23~6/24

2022-06-24 22:33:03  阅读:113  来源: 互联网

标签:24 邮票 return 23 int 枚举 now 10


1.除法uva725

题面:输入正整数n,按从小到大顺序输出所有形如abcde/fghij=n的表达式,其中aj恰好为09的一个排列,可以有前导零

注意点:

  1. 前导零只可能出现在除数中,即被除数为和除数最多为五位数

  2. 通过对除数进行dfs枚举,并记录该枚举方案是否有前导零,计算得到被除数,再检验每一个数字是否存在即可

#include<bits/stdc++.h>
using namespace std;
int n;
bool vis[10],flag;
int v[10];
int check(int a,int b){
	memset(v,0,sizeof v);
	int m;
	if(((a / 100000) > 0) || ((b / 100000) > 0))return 0;
	while(a){
		m = a % 10;
		a /= 10;
		v[m] += 1;
	}
	while(b){
		m = b % 10;
		b /= 10;
		v[m] += 1;
	}
	if(v[0] > 1)return 0;
	for(int i = 1; i <= 9; i++){
		if(v[i] != 1)return 0;
	}
	if(v[0] == 0)return 2;
	return 1;
}
void dfs(int cnt,int tot,int now){
	if(cnt >= tot){
		int m = n * now;
		if(check(m,now)){
			if(check(m,now) == 1)printf("%d / %d = %d\n",m,now,n);
			else printf("%d / 0%d = %d\n",m,now,n);
			flag = 1;
		}
		return;
	}
	for(int i = 0; i <= 9; i++){
		if(cnt == 0 && i == 0)continue;
		if(!vis[i]){
			now *= 10;
			now += i;
			vis[i] = 1;
			dfs(cnt + 1,tot,now);
			vis[i] = 0;
			now /= 10;
		}
	}
}
int main(){
	int cnt = 1;
	while(cin >> n){
		if(n == 0){
			break;
		}
		if(cnt != 1)puts("");
		flag = 0;
		for(int i = 1; i <= 5; i++){
			dfs(0,i,0);
		}
		cnt++;
		if(!flag)printf("There are no solutions for %d.\n",n);
	}
} 

2.分数拆分uva10976

题面:输入正整数k,找到所有正整数x >= y,使1/k = 1/x + 1/y

  1. 初看此题,容易直接将分数运算转换为浮点运算,然而限于精度等问题,这种思路是行不通的,因此,可以尝试通过枚举x或y与k通分进行运算,并检查是否符合题意即可
  2. 枚举x还是y?由关系式可以得到,2y<=k,因此y的范围可以很好确定,然而x不好确定其上界,因此选择y进行枚举
  3. 进行检验时,只需要检查一下算出的分数是否可以化简成1/x的形式即可,这里采用辗转相除法来计算最大公倍数
#include<bits/stdc++.h>
using namespace std;
int k;
const int MAXN = 10000;
int find(int a,int b){
	if(b == 0){
		return a;
	}
	int c = a % b;
	return find(b,c);
}
int get(int a,int b){
	int s = find(a,b);
	int num = (a / s) * (b / s) * s;
	return num;
}
struct item{
	int k,x,y; 
}w[MAXN]; 
int main(){
	freopen("B.out","w",stdout);
	while(cin >> k){
		int cnt = 0;
		for(int y = k + 1; y <= 2 * k; y++){
			int s = get(y,k);
			int a = s / k;
			int b = s / y;
			int m = a - b;
			if(s % m == 0){
				s /= m;
				cnt++;
				w[cnt].k = k;
				w[cnt].x = s;
				w[cnt].y = y;
			}
		}
		cout << cnt << endl;
		for(int i = 1; i <= cnt; i++){
			printf("1/%d = 1/%d + 1/%d\n",w[i].k,w[i].x,w[i].y);
		}
	}
}

3.邮票面值设计洛谷p1021

如题:给定一个信封,最多只允许粘贴 N 张邮票,计算在给定 K(N+K≤15)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值 MAX,使在 1 至 MAX 之间的每一个邮资值都能得到。

破题:设计邮票的面值 = 枚举邮票的面值 确定MAX = 根据所枚举出来的邮票来计算所能取到的最大的值

  1. 一个小细节:既然要求能够满足1—MAX之间的组合,这就意味着1必将是所取的邮票面值的一个
  2. 枚举的上界如何确定?这也是此题的一个难点之一,确定好了就过,否则TLE。
    由于要求可以组合成的面额必须连续,因此,如果本次枚举的面额过于大,则必然不能连续。易知,若面额max > n + 1,则无法构成连续组合!,因此,枚举的上界得以确定,该题结束一半。
  3. 确定MAX,自然想到通过动态规划来确定每种面额至少需要多少张邮票来组成(面额最大为n*(n + 1)),若张数大于最多的个数,则无法做到连续。(完)
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 10005;
int dp[MAXN],m,n,k,ans,mon[20],an[20];
int cal(int x){
	int ma = 0;
	ma = n * x;
	memset(dp,0x3f,sizeof dp);
	dp[0] = 0;
	for(int i = 1; i <= k; i++){
		for(int j = mon[i]; j <= ma; j++){
			dp[j] = min(dp[j],dp[j - mon[i]] + 1);
		}
	}
	for(int i = 1; i <= ma; i++){
		if(dp[i] > n)return i - 1;
	}
	return ma;
}
void dfs(int cnt,int last,int last1){
	if(cnt > k){
		int sum = cal(mon[k]);
//		cout << last << "**" << sum << endl; 
//		for(int i = 1; i <= k; i++){
//			cout << mon[i] << " "; 
//		}
//		puts("");
		if(ans < sum){
			ans = sum;
			for(int i = 1; i <= k; i++){
				an[i] = mon[i];
			}
		}
		return; 
	}
	for(int i = last + 1; i <= last1 + 1; i++){
		mon[cnt] = i;
		int x = cal(i);
		dfs(cnt + 1,i,x); 
		mon[cnt] = 0; 
	}
}
int main(){
	cin >> n >> k;
	m = (n + 1) * n;
	mon[1] = 1;
	dfs(2,1,n);
	for(int i = 1; i <= k; i++){
		cout << an[i] << " ";
	}
	puts("");
	printf("MAX=%d\n",ans);
}

4.洛谷p1118

  1. 杨辉三角加dfs,较轻松

标签:24,邮票,return,23,int,枚举,now,10
来源: https://www.cnblogs.com/CZ-9/p/16410394.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有