【链接】:https://www.luogu.org/problemnew/show/P1618

题目描述

将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试求出所有满足条件的三个三位数,若无解,输出“No!!!”。

//感谢黄小U饮品完善题意

输入输出格式

输入格式:

三个数,A B C。

输出格式:

若干行,每行3个数字。按照每行第一个数字升序排列。

输入输出样例

输入样例#1:
复制

1 2 3
输出样例#1: 复制

192 384 576
219 438 657
273 546 819
327 654 981

说明

保证A<B<C

【分析】:

#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int a,b,c,num,i1,i2,i3,flag=;
cin>>i1>>i2>>i3;
for(num=;num<=;num++){
a=i1*num;b=i2*num;c=i3*num;
if((a/+a/%+a%+b/+b/%+b%+c/+c/%+c%==)&&((a/)*(a/%)*(a%)*(b/)*(b/%)*(b%)*(c/)*(c/%)*(c%)==)){
cout<<a<<" "<<b<<" "<<c<<endl;
flag=;
}
}
if(flag==){
cout<<"No!!!";
}
return ; }

普通枚举

1.

枚举每一个可能的数,将三个倍数保存在数组中,再排序,最后通过和标准的“123456789”比较,如果相同,则满足条件。这样用一个常量数组,可以简化计算,不需要过多的思考。所以说常量数组大法真的好~因为之前做过三连击的简单版,就有了思维定式,枚举总是从123开始,所以最后一个(数据是123 456 789)总是错。最后一个过不去的同学可以试试从1开始枚举,就会过去了。

#include <bits/stdc++.h>

using namespace std;

char stdanard[]="";

int a,b,c;

int main()
{
int flag=;
cin>>a>>b>>c;
for(int i=;i<=;i++)
{
char buf[];//开大防止溢出
sprintf(buf,"%d%d%d",a*i,b*i,c*i);
sort(buf,buf+);
if(strcmp(stdanard,buf)==)
{
flag=;
printf("%d %d %d\n",a*i,b*i,c*i);
}
}
if(flag) puts("No!!!");
return ;
}

sprintf

2.我和大部分人思路基本一样,不一样的地方在于对三个数组成的9个数的拆分上,我用的是sstream头文件,将三个数放到一个字符串中去,这样就不用%或者/去费力拆分了,写起来更优雅,然后将字符串每个数加起来 乘起来,即可验证是否为不同的9个数。

/*
对三个数组成的9个数的拆分上,用的是sstream头文件,
将三个数放到一个字符串中去,
这样就不用%或者/去费力拆分了,写起来更优雅,
然后将字符串每个数加起来 乘起来,即可验证是否为不同的9个数。
*/
#include <bits/stdc++.h> using namespace std; stringstream ss;
string str;
int cnt=;
int a,b,c; int main()
{
cin>>a>>b>>c; for(int i=;i<=;i++)
{
int j=i*b/a;
int k=i*c/a;
int sum=;
int pro=;
ss<<i<<j<<k;
ss>>str;
ss.clear(); for(int j=;j<;j++)
{
sum+=str[j]-'';
pro*=str[j]-'';
} if(sum== && pro==)
{
cout<<i<<" "<<j<<" "<<k<<" "<<endl;
cnt++;
} }
if(!cnt) puts("No!!!");
return ;
}

stringstream

3.

/*
其实判断是否相等不需要if(a==b&&b==c...)这样乱七八糟的打一大坨,一个数组就能完成。如下:
*/
#include <bits/stdc++.h> using namespace std; int d[];//数组d判断位数是否相等。
int main()
{
float x,y,z;
int a,b,c,t=,j=;//j判断是否有解
cin>>x>>y>>z;//即A、B、C
for(a=;a<=;a++)//枚举最小的那个数
{
b=y*a/x;
c=z*a/x;
d[a/]++;
d[(a%)/]++;
d[a%]++; d[b/]++;
d[(b%)/]++;
d[b%]++; d[c/]++;
d[(c%)/]++;
d[c%]++;
for(int bb=;bb<=;bb++)
{
if(d[bb]==) t=;//由于总共只有九个数字,若有一个数没有出现,就说明有数字重复了。
d[bb]=;//归零
}
if(t==) {cout<<a<<" "<<b<<" "<<c<<endl;j=;}//若有解,输出a、b、c
t=;
}
if(!j) cout<<"No!!!";
return ;
}

数组技巧性枚举

# include <stdio.h>
# define MUL(x) (x%)*(x/%)*(x/) //一个三位数x所包含的3个数的乘积为MUL(x)
# define ADD(x) (x%)+(x/%)+(x/) //一个三位数x所包含的3个数的总和为ADD(x)
const product=********; //数字1—9的乘积为product
const int sum=++++++++; //数字1—9的总和为sum
int main()
{
int A,B,C,a=,Yes=; //变量Yes用于检测是否有解
scanf("%d %d %d",&A,&B,&C); //输入3个三位数的比例A:B:C(A<B<C且为最简比)
while(++a*A<); //保证这3个数中最小的数是三位数
for(;a*C<;a++) //保证这3个数中最大的数是三位数
if(product==MUL(a*A)*MUL(a*B)*MUL(a*C) //倘若它们所包含的9个数的乘积恰好为product
&& sum==ADD(a*A)+ADD(a*B)+ADD(a*C)) //并且总和恰好为sum时,说明没有重复数字和0
Yes=printf("%i %i %i\n",a*A,a*B,a*C); //输出这3个由1—9组成的三位数,并给Yes赋值
if(!Yes) //若无解
puts("No!!!"); //则输出“No!!!”
return ;
}

技巧性枚举

4.

#include<iostream>
using namespace std;
int x[]={},a,b,c; //x[1]~x[9]为当前位置的数字 先把三个三位数合成一个9(10)位数的大数组
bool used[]={},ans=false;
//used数组表示该数字的使用情况 避免重复 ans判断是否有答案
int cons(int m){ //将数组拆分成三个三位数
int sum=;
for(int i=*m-;i<=*m;i++){
sum*=;
sum+=x[i];
}
return sum;
}
void solve(int n){
if(n==&&cons()*b==cons()*a&&cons()*c==cons()*a){ //当n=10时x数组数字存满 开始判断
cout<<cons()<<" "<<cons()<<" "<<cons()<<endl;
ans=true;
return;
}
for(int i=;i<=;i++){
if(!used[i]){
x[n]=i; //存数字
used[i]=; //该数字被使用
solve(n+); //下一位继续调用
used[i]=; //恢复
}
}
return;
}
int main(){
cin>>a>>b>>c;
solve(); //开始搜索
if(!ans) cout<<"No!!!"; //ans!=true即输出"No!!!"
return ;
}

DFS

5.STL中的next_permutation函数提供下一个排列功能,是用生成法实现的,所以速度要比搜索快多了。

#include<bits/stdc++.h>
using namespace std;
int a[]={,,,,,,,,,};
int main()
{
int A,B,C,h=;
cin>>A>>B>>C;
int t=A*B*C;
A=t/A;
B=t/B;
C=t/C;
do{
if((*a[]+*a[]+a[])*A==(*a[]+*a[]+a[])*B&&(*a[]+*a[]+a[])*A==(*a[]+*a[]+a[])*C)//如果符合比例;
{
cout<<a[]<<a[]<<a[]<<" "<<a[]<<a[]<<a[]<<" "<<a[]<<a[]<<a[]<<endl;//输出
h++;
}
}while(next_permutation(a+,a+));//STL中的下一个排列函数;
if(h==) cout<<"No!!!";//没有解输出NO;
return ;
}

next_permutation()

#include<iostream>
#include<algorithm>
using namespace std;
int a[] = { , , , , , , , , };
bool isSame(int v[], int a[]) {
for (int i = ; i != ; i++)
if (v[i] != a[i])
return false;
return true;
}
int main()
{
int A, B, C;
int visit[] = { };
int pos;
bool flag = false;
cin >> A >> B >> C;
do {
int x = a[] * + a[] * + a[];
int y = a[] * + a[] * + a[];
int z = a[] * + a[] * + a[];
int a[] = { x, y, z };
sort(a, a + );
if (!isSame(visit, a)) {
if ((double)y / x == (double)B / A && (double)z / x == (double)C / A && (double)z / y == (double)C / B) {
cout << a[] << " " << a[] << " " << a[] << endl;
flag = true;
}
}
} while (next_permutation(a, a + ));
if (flag == false)
cout << "No!!!" << endl;
return ;
}

5.2

洛谷 P1618 三连击(升级版)【DFS/next_permutation()/技巧性枚举/sprintf】的更多相关文章

  1. 洛谷——P1618 三连击(升级版)

    P1618 三连击(升级版) 题目描述 将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试求出所有满足条件的三个三位数,若无解,输出“No!!!”. //感谢 ...

  2. (水题)洛谷 - P1618 - 三连击(升级版)

    https://www.luogu.org/problemnew/show/P1618 枚举所有的A,最多 $A_9^3$ ,然后生成B和C(先判断是不是能够生成),判断有没有重复数字(比之前那个优雅 ...

  3. 洛谷 P1618 三连击(升级版)

    题目描述 将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试求出所有满足条件的三个三位数,若无解,输出“No!!!”. //感谢黄小U饮品完善题意 输入输出格 ...

  4. Java实现 洛谷 P1618 三连击(升级版)

    import java.util.Arrays; import java.util.Scanner; public class Main { private static Scanner cin; p ...

  5. 洛谷 p1008三连击

    洛谷 p1008三连击 题目背景 本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序. 题目描述 将1,2, ⋯,9共99个数分成3组,分别组成3个三位数, ...

  6. 【题解】洛谷P3166 [CQOI2014] 数三角形(组合+枚举)

    洛谷P3166:https://www.luogu.org/problemnew/show/P3166 思路 用组合数求出所有的3个点组合(包含不合法的) 把横竖的3个点共线的去掉 把斜的3个点共线的 ...

  7. 题解【洛谷P1618】 三连击(升级版)

    设三个数分别为n1.n2.n3,因为三个数的比为A:B:C,取一份量i,使得A·i=x,B·i=y,C·i=z(·是*的意思). 所以我们的代码只需要枚举i,并以此判断n1.n2.n3是否为三位数且包 ...

  8. 洛谷P1120小木棍[DFS]

    题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...

  9. 洛谷P1605 迷宫 (DFS)

    题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...

随机推荐

  1. 动态规划:HDU1176-免费馅饼

    免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  2. 笔记-python-build-in-types

    笔记-python-build-in-types 注:文档内容来源为Python 3.6.5 documentation 1.      built-in types 1.1.    真值测试 所有对 ...

  3. 15,scrapy中selenium的应用

    引入 在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生如果直接用scrapy对其url发请求,是获取不到那部分动态加载出来的数据值,但是通过观察会发现,通过浏览器 ...

  4. Codeforces 664D Graph Coloring 二分图染色

    题意: 一个无向图的每条边为红色或蓝色,有这样一种操作:每次选一个点,使与其相邻的所有边的颜色翻转. 求解是否可以经过一系列操作使所有的边颜色相同,并输出最少操作次数和相应的点. 分析: 每个点要么选 ...

  5. Redis实现之字符串

    简单动态字符串 Redis中的字符串并不是传统的C语言字符串(即字符数组,以下简称C字符串),而是自己构建了一种简单动态字符串(simple dynamic string,SDS),并将SDS作为Re ...

  6. MySQL基础9-主键约束、外键约束、等值连接查询、一对一和多对多关系

    1.主键约束和外键约束 外键约束 * 外键必须是另一表的主键的值(外键要引用主键!) * 外键可以重复 * 外键可以为空 * 一张表中可以有多个外键! 概念模型在数据库中成为表 数据库表中的多对一关系 ...

  7. java多线程安全的问题

    多线程中一定会遇到线程安全的问题,也就是在同一时间N条线程操作了同一变量,这个变量也叫做共享变量. 举例:(错误的示范) 设计一个投票系统,多个人可以对同一个的票数进行投票,下面看具体代码: 代码: ...

  8. ogre3D学习基础19 --- 材质的继承,纹理的滚动与旋转

    以上一节为基础,废话不多说. 首先新增一个节点,用于比较显示 //新增一个节点 ent = mSceneMgr->createEntity("Quad"); ent-> ...

  9. copy & deepcopy

    1 import copy 2 3 字典参照列表结论,看是否有深层嵌套. 4 a = {'name':1,'age':2} 5 b = a 6 a['name'] = 'ff' 7 print(a) ...

  10. c4d 帮助 prime r16 usage

    c4d   帮助 prime cinema 4d   prime    c4d  基础 前言   usage 开始 双击程序图标   双击一个场景文件   用开始菜单  windows 二选一   从 ...