/*———————————————————————————————————————————————————————————
【结果填空题】T1     (分值:3)
题目:煤球数目有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),
....
如果一共有100层,共有多少个煤球?
请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。1        *        (1)
2       ***        (3)
3     ******    (6)
4   **********  (10)
5 ..............(15)
————————————————————————————————————————————————————————————*/
//

/*** pre 定义上一层* plus 定义增量差值 */
#include<iostream>
using namespace std ;
int main(int argc, char const *argv[])
{int pre = 1 ; //
    int plus = 2 ; //
    long sum = 1 ;for (int k = 2; k <= 100; ++k){sum += (pre+plus) ;pre = pre + plus ;//sum+=preplus++ ;}cout << sum << endl ;return 0;
}
//结果:171700/*———————————————————————————————————————————————————————————
【结果填空题】T2     (分值:5)
题目:生日蜡烛某君从某年开始每年都举办一次生日party,
并且每次都要吹熄与年龄相同根数的蜡烛。
现在算起来,他一共吹熄了236根蜡烛。
请问,他从多少岁开始过生日party的?
请填写他开始过生日party的年龄数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
————————————————————————————————————————————————————————————*/
//
/*
思路:236 i ~ j
for(i:100)
for(j:100)
等差数列求和:(i+j)/2*(j-i-1)
(a0+a0*(n-1)*d/2)*n*/#include<iostream>
using namespace std ;
int main()
{//枚举两个年龄for (int i = 1; i < 100; ++i){for (int j = i; j < 100; ++j){if((i*j)*(j-i-1)/2==236)cout << i << " "<< j << endl ;}}//枚举生日举办次数for (int i = 1; i < 100; ++i){int t = i*(i-1)/2 ;if((236-t)%i==2){//输出首项cout << (236-t)/i << " " << i << endl ;}}return 0 ;
}/*———————————————————————————————————————————————————————————
【结果填空题】T3     (分值:11)
题目:凑算式B      DEF
A + --- + ------- = 10C      GHI(如果显示有问题,可以参见【图1.jpg】)
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
————————————————————————————————————————————————————————————*/
//
//全排列
#include<iostream>
#include<math.h>using namespace std ;
int a[] = {1,2,3,4,5,6,7,8,9} ;
int ans ;
bool check()
{int x = a[3] * 100 + a[4] * 10 + a[5] ;int y = a[6] * 100 + a[7] * 10 + a[8] ;if((a[1]*y + a[2]*x) % (y*a[2])==0 && a[0] + (a[1]*y + a[2]*x)/(y*a[2]==10)) return true ;return false ;
}//递归回溯生成全排列  适用于无重复元素的情况
//考虑前k位,前面已经排定
void f(int k)
{if(k==9) {//其中一种排列已经生成if(check()) ans++ ;}//从k往后的每个数字都可以放在k位for (int i = k; i < 9; ++i){{int t=a[i]; a[i]=a[k]; a[k]=t;}f(k+1) ; //递归{int t=a[i]; a[i]=a[k]; a[k]=t;} //回溯
    }
}int main()
{f(0) ;cout << ans << endl ;return 0 ;
}//思路二 next_permutation()

#include<iostream>
#include<math.h>using namespace std ;
int a[] = {1,2,3,4,5,6,7,8,9} ;
int ans ;
bool check()
{int x = a[3] * 100 + a[4] * 10 + a[5] ;int y = a[6] * 100 + a[7] * 10 + a[8] ;if((a[1]*y + a[2]*x) % (y*a[2])==0 && a[0] + (a[1]*y + a[2]*x)/(y*a[2]==10)) return true ;return false ;
}int main()
{do{if(check()) ans++ ;}while(next_permutation(a,a+9)) ;cout << ans << endl ;return 0 ;
}/*———————————————————————————————————————————————————————————
【代码填空题】T4     (分值:9)
题目:快速排序
排序在各种场合经常被用到。
快速排序是十分常用的高效率的算法。
其思想是:先选一个“标尺”,
用它把整个队列过一遍筛子,
以保证:其左边的元素都不大于它,其右边的元素都不小于它。
这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。下面的代码是一种实现,请分析并填写划线部分缺少的代码。
————————————————————————————————————————————————————————————*/
//
#include <stdio.h>void swap(int a[], int i, int j)//交换
{int t = a[i];a[i] = a[j];a[j] = t;
}int partition(int a[], int p, int r)
{int i = p; //i指向大于x  ——>找大int j = r + 1; //j指向小于等于x ——>找小int x = a[p];while(1){while(i<r && a[++i]<x);while(a[--j]>x);if(i>=j) break;swap(a,i,j);}/*代码填空处swap(a,p,j) ; //______________________; */return j;
}void quicksort(int a[], int p, int r)
{if(p<r){int q = partition(a,p,r); //q为标尺quicksort(a,p,q-1);quicksort(a,q+1,r);}
}int main()
{int i;int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};int N = 12;quicksort(a, 0, N-1); //排序for(i=0; i<N; i++) printf("%d ", a[i]);printf("\n");return 0;
}/*———————————————————————————————————————————————————————————
【代码填空题】T5     (分值:13)
题目:抽签X星球要派出一个5人组成的观察团前往W星。
其中:
A国最多可以派出4人。
B国最多可以派出2人。
C国最多可以派出2人。
....那么最终派往W星的观察团会有多少种国别的不同组合呢?下面的程序解决了这个问题。
数组a[] 中既是每个国家可以派出的最多的名额。
程序执行结果为:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
....
(以下省略,总共101行)
————————————————————————————————————————————————————————————*/
//递归填空
#include <stdio.h>
#define N 6
#define M 5
#define BUF 1024
/*** k = 数组的下标 * m代表人数,初始为5* b缓冲字符串*/void f(int a[], int k, int m, char b[])
{int i,j;if(k==N){ b[M] = 0; //字符串结尾的标志if(m==0) {printf("%s\n",b); ans++ ;}return;}//递归for(i=0; i<=a[k]; i++){ //试着将k国家,排除i人for(j=0; j<i; j++) b[M-m+j] = k+'A'; ////填充buf,有i人就填i个国家符号(k+'A')/*代码填空处f(a,k+1,m-i,b) ; ______________________;  */f(a,k+1,m-i,b) ; }
}
int main()
{    int  a[N] = {4,2,2,1,1,3};char b[BUF];f(a,0,M,b);printf("%d\n",ans) ;return 0;
}/*———————————————————————————————————————————————————————————
【结果填空题】T6     (分值:19)
题目:方格填数
如下的10个格子+--+--+--+|  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |
+--+--+--+(如果显示有问题,也可以参看【图1.jpg】)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
————————————————————————————————————————————————————————————*/
// 全排列 + 检查
#include<iostream>
using namespace std ;int a[10] = {0,1,2,3,4,5,6,7,8,9} ;
int ans ;void check()//检查
{if(abs(a[0] - a[1])==1 ||abs(a[0] - a[3])==1 ||abs(a[0] - a[4])==1 ||abs(a[0] - a[5])==1 ||abs(a[1] - a[2])==1 ||abs(a[1] - a[4])==1 ||abs(a[1] - a[5])==1 ||abs(a[1] - a[6])==1 ||abs(a[2] - a[5])==1 ||abs(a[2] - a[6])==1 ||abs(a[3] - a[4])==1 ||abs(a[3] - a[7])==1 ||abs(a[3] - a[8])==1 ||abs(a[4] - a[5])==1 ||abs(a[4] - a[7])==1 ||abs(a[4] - a[8])==1 ||abs(a[4] - a[9])==1 ||abs(a[5] - a[6])==1 ||abs(a[5] - a[8])==1 ||abs(a[5] - a[9])==1 ||abs(a[6] - a[9])==1 ||abs(a[7] - a[8])==1 ||abs(a[8] - a[9])==1 ||)return false ;return true ;
}/*考虑第k个位置,一般从0开始*/
void f(int k)//递归函数
{
//出口 if(k==0){bool b  = check() ; //检查if(b)ans++ ;return  ;}for (int i = k; i < 10; ++i)//尝试将位置i与位置k交换,以此确定k位的值
    {int t = a[i] ;a[i] = a[k] ;a[k] = t ;    }f(k+1) ;//回溯
    {int t = a[i] ;a[i] = a[k] ;a[k] = t ;}}int main()
{f(0) ; //初始化cout << ans << endl ;return 0 ;
}//思路2 使用二维数组
/* 3*4 ——> 5*6
-10-10-10-10-10+--+--+--+|  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |
+--+--+--+
-10-10-10-10-10*/
#include<iostream>
using namespace std ;int a[5][6] ;
int vis[10] ;
int ans ;bool check(int i ,int y) //检查
{for (int x = x-1; x<= i+1; ++x){for (int y = j-1; y <= j+1; ++y){if(abs(a[x][y]-a[i][j])==1)return false ;}}return true ;
}//全排列
void f(int k,int y)
{if(x==3 & y == 4){ans++ ;return ;}//从0-9中抓一个for (int i = 0; i < 10; ++i){if(vis[i]==0) //i没有没用过
        {a[x][y] = i ; //填数if(!check(x,y)) //不合法,恢复并continue
            {a[x][y] = -10 ;continue ;}vis[i] = 1 ;if(y ==4)f(x+1,1) ; //换行else  f(x,y+1) ; //继续填右侧的格子
            {vis[i] = 0 ;a[x][y] = -10 ;} }}
}//初始化
void init()
{for (int i = 0; i < 5; ++i){for (int j = 0; j < 6; ++j){a[i][j] = -10 ; //初始化格式
        }}
}int main(int argc, char const *argv[])
{init() ; //初始化f(1,2) ; //递归调用cout << ans <<endl ; //打印输出return 0;
}
/*本思路可以防止下标越界的问题*//*———————————————————————————————————————————————————————————
【结果填空题】T7     (分值:19)
题目:剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
————————————————————————————————————————————————————————————*/
//
/*
1  2  3  4
5  6  7  8
9  10 11 12 思路1:每个格子作为起点,dfs连五张,去重->结果思路2:暴力枚举,所有的五张组合,检查它们是不是一个连通块。 */
// 12/13 寒假作业   12/5 dfs/*思路1: 生成的方法有太多的重复,效率低下
//此题和13年剪格子有相似之处,但是那个题的限制条件是格子数值之和为总和的一半,此题则限制只能是5个格子
//单纯的dfs无法解决T字型连通方案
//本题的解决办法是,找出任意5个格子,判断是否连通*/
#include <algorithm>
#include <iostream>using namespace std;int ans;bool check(int arr[12]);void dfs(int g[3][4], int i, int j);int main(int argc, const char *argv[]) {int per[] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};do {if (check(per))ans++;} while (next_permutation(per, per + 12));cout << ans << endl;return 0;
}bool check(int arr[12]) {int g[3][4];memset(g, 0, sizeof(g));
//将相应位置标注为1for (int i = 0; i < 3; ++i) {for (int j = 0; j < 4; ++j) {if (arr[i * 4 + j] == 1)g[i][j] = 1;}}
//    经典连通块计算int cnt = 0;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 4; ++j) {if (g[i][j] == 1) {dfs(g, i, j);cnt++;}}}return cnt == 1;
}void dfs(int g[3][4], int i, int j) {g[i][j] = 0;if (i + 1 <= 2 && g[i + 1][j] == 1) dfs(g, i + 1, j);if (i - 1 >= 0 && g[i - 1][j] == 1) dfs(g, i - 1, j);if (j + 1 <= 3 && g[i][j + 1] == 1) dfs(g, i, j + 1);if (j - 1 >= 0 && g[i][j - 1] == 1) dfs(g, i, j - 1);
}//思路2:
#include <algorithm>
#include <iostream>
#include <set>using namespace std;int a[]={0,0,0,0,0,0,0,1,1,1,1,1};//它的每个排列代表着12选5的一个方案
int ans;
void dfs(int g[3][4],int i , int j){g[i][j]=0;if(i-1>=0&&g[i-1][j]==1)dfs(g,i-1,j);if(i+1<=2&&g[i+1][j]==1)dfs(g,i+1,j);if(j-1>=0&&g[i][j-1]==1)dfs(g,i,j-1);if(j+1<=3&&g[i][j+1]==1)dfs(g,i,j+1);
}
bool check(){int g[3][4];
//    将某个排列映射到二维矩阵上for (int i = 0; i < 3; ++i) {for (int j = 0; j < 4; ++j) {if(a[i*4+j]==1) g[i][j]=1;else g[i][j]=0;}}int cnt=0;//连通块的数目
//    g上面就有5个格子被标记为1,现在才用dfs做连通性检查,要求只有一个连通块for (int i = 0; i < 3; ++i) {for (int j = 0; j < 4; ++j) {if(g[i][j]==1){dfs(g,i,j);cnt++;}}}return cnt==1;
}
set<string> s1;
void a2s(string &s){for (int i = 0; i < 12; ++i) {s.insert(s.end(),a[i]+'0');}
}
bool isExist(){string a_str;a2s(a_str);if(s1.find(a_str)==s1.end()){s1.insert(a_str);return false;} elsereturn true;
}
void f(int k){if(k==12){if(!isExist()&&check()){ans++;}}for (int i = k; i < 12; ++i) {{int t=a[i];a[i]=a[k];a[k]=t;}f(k+1);{int t=a[i];a[i]=a[k];a[k]=t;}}
}
int main(int argc, const char *argv[]) {f(0);printf("%d",ans);
//string _s;
//a2s(_s);
//cout<<_s<<endl;return 0;
}//思路3:
#include <algorithm>
#include <iostream>using namespace std;//它的每个排列代表着12选5的一个方案
int a[] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
int ans;void dfs(int g[3][4], int i, int j)
{g[i][j] = 0;if (i - 1 >= 0 && g[i - 1][j] == 1)dfs(g, i - 1, j);if (i + 1 <= 2 && g[i + 1][j] == 1)dfs(g, i + 1, j);if (j - 1 >= 0 && g[i][j - 1] == 1)dfs(g, i, j - 1);if (j + 1 <= 3 && g[i][j + 1] == 1)dfs(g, i, j + 1);
}bool check(int path[12])
{int g[3][4];
//    将某个排列映射到二维矩阵上for (int i = 0; i < 3; ++i) {for (int j = 0; j < 4; ++j) {if (path[i * 4 + j] == 1) g[i][j] = 1;else g[i][j] = 0;}}int cnt = 0;//连通块的数目
//    g上面就有5个格子被标记为1,现在才用dfs做连通性检查,要求只有一个连通块for (int i = 0; i < 3; ++i) {for (int j = 0; j < 4; ++j) {if (g[i][j] == 1) {dfs(g, i, j);cnt++;}}}return cnt == 1;
}bool vis[12];void f(int k, int path[12])
{if (k == 12) {if (check(path)) {ans++;}}for (int i = 0; i < 12; ++i) {if (i>0&&a[i]==a[i-1]&&!vis[i-1])continue;//现在准备选取的元素和上一个元素相同,但是上一个元素还没被使用if(!vis[i]){//没有被用过的元素可以抓入到pathvis[i]=true;//标记为已访问path[k]=a[i];//将a[i]填入到path[k]中f(k + 1, path);//递归vis[i]=false;//回溯
        }}
}int main(int argc, const char *argv[])
{int path[12];f(0, path);printf("%d", ans);return 0;
}/*———————————————————————————————————————————————————————————
【代码编程题】T8     (分值:21)
题目:四平方和四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序:
0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,
最后输出第一个表示法程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开例如,输入:
5
则程序应该输出:
0 0 1 2再例如,输入:
12
则程序应该输出:
0 2 2 2再例如,输入:
773535
则程序应该输出:
1 1 267 838资源约定:
峰值内存消耗 < 256M
CPU消耗  < 3000ms请严格按要求输出,不要画蛇添足地打印类似:
“请您输入...” 的多余内容。所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,
不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>,
不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。————————————————————————————————————————————————————————————*/
//枚举+优化
//优化:采用缓存来空间换时间/*思路1:
枚举abcd
for(a)    0~a^2for(b)    0~b^2for(c)    0~c^2for(d)    0~d^2    */
#include<iostream>
#include<cstdio>
#include<map>
int N ;using namespace std ;int main()
{scanf("%d",&N) ;//
    for (int c = 0; c*c <= N/2; ++c){for (int d = c; c*c+d*d <= N ; ++d){if(cache.find(c*c+d*d)==cache.end())cache[c*c+d*d] = c ;}//
        for (int a = 0; a*a<= N/4; ++a){for (int b = a; a*a+c*c <= N/2; ++b){if(cache.find(N-a*a+b*b)!=cache.end()) ;int c = cache[N-(a*a+b*b+c*c)] ;int d = int(sqrt(N-(a*a+b*b+c*c)) ;printf("%d %d %d %d\n",a,b,c,d) ;return 0 ;}}}return 0 ;
}/*———————————————————————————————————————————————————————————
【代码编程题】T9    (分值:23)
题目:交换瓶子有N个瓶子,编号 1 ~ N,放在架子上。
比如有5个瓶子:
2 1 3 5 4
要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换2次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。
输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。例如,输入:
5
3 1 2 5 4程序应该输出:3
再例如,输入:
5
5 4 3 2 1程序应该输出:2
资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,
不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>,
不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
————————————————————————————————————————————————————————————*/
/*3   2   1   5   4
[1] [2] [3] [4] [5] */// 贪心
#include <iostream>using namespace std;
int n;
int a[10001];
int ans;int pos(int x)
{for (int i = 1; i <= n; ++i) {if (a[i] == x)return i;}return -1;
}void swap(int i, int j)
{int t = a[i];a[i] = a[j];a[j] = t;
}void printArr() {for (int i = 1; i <= n; ++i) {printf("%d ", a[i]);}printf("\n");
}int main(int argc, const char *argv[])
{// 处理输入scanf("%d", &n);for (int i = 1; i <= n; ++i) {scanf("%d", &a[i]);}//遍历i:1-Nfor (int i = 1; i <= n; ++i) {//如果a[i]=i,已经到位if (a[i] == i)continue;//否则先找到i在a中的位置pos(i)和i位交换——swap(a,pos(i),i)else {swap(pos(i), i);ans++;}}//printArr();printf("%d\n", ans);return 0;
}/*———————————————————————————————————————————————————————————
【代码编程题】T10    (分值:31)
题目:最大比例X星球的某个大奖赛设了M级奖励。每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。比如:
16,24,36,54
其等比值为:3/2现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。输入格式:
第一行为数字 N (0<N<100),表示接下的一行包含N个正整数
第二行N个正整数Xi(Xi<1 000 000 000 000),用空格分开。
每个整数表示调查到的某人的奖金数额
要求输出:
一个形如A/B的分数,要求A、B互质。表示可能的最大比例系数
测试数据保证了输入格式正确,并且最大比例是存在的。例如,输入:
3
1250 200 32程序应该输出:25/4再例如,输入:
4
3125 32 32 200程序应该输出:5/2再例如,输入:
3
549755813888 524288 2程序应该输出:4/1资源约定:
峰值内存消耗 < 256M
CPU消耗  < 3000ms请严格按要求输出,不要画蛇添足地打印类似:
“请您输入...” 的多余内容。所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,
不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>,
不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
————————————————————————————————————————————————————————————*/
//
/*
等比数列:a0、a1、a2、a3、a4
等比数列的性质:
a3          p
——   ——>  (———)^2
a0          q*/
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>using namespace std ;
typedef long long LL ;
int N ;
LL data[100] ; struct Ratio{LL x,y ;Ratio(LL _x,LL _y):x(_x),(_y){LL _gcd = gcd(x,y) ;x /= _gcd ;y /= _gcd ;}LL gcd(LL a,LL b){if(b==0) return a ;return gcd(b,a%b) ;}
} ;
//存储比值
vector<Ratio> ratios ;int main()
{//处理输入scanf("%d",&n) ;for (int i = 0; i < N; ++i) //扫描输入数据
    {scanf("%lld",&data[i]) ;}//排序sort(data,data+N) ;//两两比值,以分数形式存储,vectorfor (int i = 0; i < N-1; ++i){if(data[i+1]!=data[i])//去重ratios.push_back(Ratio(data[i+1],data[]i)) ;}/*对第一个比值开1-..pow(极限为40)次方作为基数,如果这个基数的分子、分母的k1k2次方恰好是其他比值的分子分母的话,基数就是答案*/for (int pow = 0; pow <= 40; ++pow){Ratio ra0 = ratios[0] ;LL x = ra0.x ;LL y = ra0.y ;LL fx = extract(x,pow) ; //对LL fy = extract(y,pow) ; //
        if(fx==-1 |\ fy ==-1) continue ; //开不出,continue //能开,就要确认所有比值的分子是fx的整数次方,所有比值的分母是fy的整数次方//计px=getPow(xx,fx),py=getPow(yy,fy),要求必须是整数且px==pybool all_match = true ;//
        for (int i = 1; i < ratios.size(); ++i){LL xx = ratios[i].x ;LL yy = ratios[i].y ;LL px = getPow(xx,fx) ;LL py = getPow(yy,fy) ;if(px == -1 || py == -1 || px != py){all_match = false ;break ;}}if(all_match){Ratio ans = Ratio(fx,fy) ;cout << ans.x << "/" << ans.y << endl ;}return 0 ;}return 0 ;
}//优化 + 完善
#include <stdio.h>
#include <iostream>
#include <vector>
#include <map>using namespace std;
typedef long long LL;
int N;
LL data[100];//结构体
struct Ratio
{LL x, y;Ratio(LL _x, LL _y) : x(_x), y(_y) {LL _gcd = gcd(x, y);x /= _gcd;y /= _gcd;}LL gcd(LL a, LL b) {if (b == 0)return a;return gcd(b, a % b);}
};vector<Ratio> ratios;
map<LL, map<LL,LL> > all_ex;//all_ex[x][pow]==x开pow次方
map<LL, map<LL,LL> > all_log;//all_log[x][y]==log_y_x,y的多少次方是x?void init() //预处理
{for (int i = 2; i < 1e6; ++i) {//底数LL cur=(LL)i*i;int pow=2;while(cur<1e12){all_ex[cur][pow]=i;all_log[cur][i]=pow;pow++;cur*=i;}}
}/*** 对x开pow次方* @param x* @param pow* @return*/
LL extract(LL x,LL pow)
{if(pow==1)return x;if(x==1)return 1;if(all_ex[x].find(pow)!=all_ex[x].end())//意味着x可以开pow整数次方return all_ex[x][pow];elsereturn -1;
}/*** 求log_base_x* @param base* @param x* @return*/LL log(LL base,LL x)
{if(base==x)return 1;if(all_log[x].find(base)!=all_log[x].end())//意味着可以得打一个k,base的k次方是xreturn all_log[x][base];return -1;
}int main(int argc, const char *argv[])
{init();freopen("/Users/zhengwei/CLionProjects/lanqiaobei2019/2016_C_A/data10/in8.txt","r",stdin);//处理输入scanf("%d", &N);for (int i = 0; i < N; ++i) {scanf("%lld", &data[i]);}//排序sort(data, data + N);//处理只有两项的特殊情况if(N==2){Ratio ans = Ratio(data[1], data[0]);cout << ans.x << "/" << ans.y << endl;return 0;}//求两两比值,以分数形式存储,vectorfor (int i = 0; i < N - 1; ++i) {if (data[i + 1] != data[i])//去重ratios.push_back(Ratio(data[i + 1], data[i]));}//对第一个比值开1~..pow(极限为40).次方,作为基数,如果这个基数也是其他比值的基数的话,该基数就是答案for (int pow = 1; pow <= 40; ++pow) {Ratio ra0 = ratios[0];LL x = ra0.x;LL y = ra0.y;LL base_x = extract(x, pow);//对x开pow次方,作为基数,去尝试LL base_y = extract(y, pow);//对y开pow次方,作为基数,去尝试if (base_x == -1 || base_y == -1)continue;//开不出,continue//能开:就要去确认所有比值的分子是fx的整数次方,所有比值的分母是fy的整数次方//计px=getPow(xx,base_x),py=getPow(yy,base_y),要求必须是整数且px==pybool all_match = true;for (int i = 1; i < ratios.size(); ++i) {LL xx = ratios[i].x;LL yy = ratios[i].y;LL log_x = log(base_x,xx);LL log_y = log(base_y,yy);if(base_y==1&&yy==1)log_y=log_x;if (log_x == -1 || log_y == -1 || log_x != log_y) {all_match = false;break;}}if (all_match) {Ratio ans = Ratio(base_x, base_y);cout << ans.x << "/" << ans.y << endl;return 0;}}return 0;
}//【2016年B组C++小结】
/*********************************************************** 01【结果填空】煤球数目  :枚举+简单计算* 02【结果填空】生日蜡烛  :等差数列求和* 03【结果填空】凑算式    :全排列* 04【代码填空】快速排序  :裸题* 05【代码填空】抽签 :递归,明确参数的含义及参数的变化方向* 06【填空填空】方格填数  :全排列 + check* 07【结果填空】剪邮票(**)  :dfs解决不了T型组合,全排列+dfs求矩阵中的连通块* 08【编程题】四平方和 :枚举+优化* 09【编程题】交换瓶子(**) :贪心* 10【编程题】最大比例(***) :数论、等比数列、预处理**********************************************************/

转载于:https://www.cnblogs.com/lx17746071609/p/10565609.html

[蓝桥杯]2016蓝桥省赛B组题目及详解相关推荐

  1. 蓝桥杯青少年创意编程python初级考察内容_第十一届蓝桥杯青少年创意编程scratch初级组编程题详解...

    点击上方"启迪少儿"即可关注 今年的12月15日是第十一届蓝桥杯青少赛的第二次选拔赛,安徽.北京.福建.广东.广西.河北.黑龙江.湖南.吉林.江苏.江西.辽宁.宁夏.山西.陕西.四 ...

  2. java dfs算法蓝桥杯题_【蓝桥杯省赛JavaB组真题详解】四平方和(2016)_疼疼蛇的博客-CSDN博客...

    原文作者:疼疼蛇 原文标题:[蓝桥杯省赛JavaB组真题详解]四平方和(2016) 发布时间:2021-02-26 15:00:01 题目描述 四平方和 四平方和定理,又称为拉格朗日定理: 每个正整数 ...

  3. 第七届蓝桥杯 2016年省赛真题(Java 大学C组)

    蓝桥杯 2016年省赛真题(Java 大学C组) 第一题:有奖猜谜 第二题:煤球数目 第三题:平方怪圈 第四题:骰子游戏 第五题:分小组 第六题:凑算式 第七题:搭积木 第八题:冰雹数 第九题:四平方 ...

  4. 2020年第十一届蓝桥杯第二场省赛B组C++题解

    2020年第十一届蓝桥杯第二场省赛B组C++题解 题单 第一题 第二题 第三题 第四题 第五题 第六题 第七题 第八题 题单 第一题 小蓝要为一条街的住户制作门牌号. 这条街一共有 2020 位住户, ...

  5. 蓝桥杯2013年国赛A组——网络寻路(DFS和中转边巧解)

    蓝桥杯2013年国赛A组--网络寻路 1.题目描述 2.输入输出 3.样例输入和输出 4.题目分析 1.首先明确,题目中的目的地有两种,一种是回到原点,一种是到达没有到达的地方 2.在路径中经过的点不 ...

  6. 2021年第十二届蓝桥杯软件类省赛python组试题及其解析。

    目录 一.卡片 二.直线 三.货物摆放 四.路径 五.回路计算 六.时间显示 七.杨辉三角 八.左孩子右兄弟 九.异或数列 十.括号序列 一.卡片 本题总分:5分 [问题描述] 小蓝有很多数字卡片,每 ...

  7. 蓝桥杯2016年C语言B组-交换瓶子

    蓝桥杯2016年C语言B组 交换瓶子 代码 交换瓶子 有N个瓶子,编号 1 ~ N,放在架子上. 比如有5个瓶子: 2 1 3 5 4 要求每次拿起2个瓶子,交换它们的位置. 经过若干次后,使得瓶子的 ...

  8. 2021年第十二届蓝桥杯软件类省赛python组

    目录 2021年第十二届蓝桥杯软件类省赛python组 1.卡片 常规做法 使用functions.Counter计数 2.直线 3.货物摆放 4.路径 5.回路计算 递归--太慢跑不出来 状态压缩D ...

  9. 使用JavaScript解答2018第九届蓝桥杯C/C++省赛A组试题

    大三时参加过第七届蓝桥杯个人赛及团队赛,转眼已经两年,最近看了看第九届蓝桥杯试题,打算用JavaScript实现一下. 题目1 标题:分数 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + ...

最新文章

  1. WPF usercontrol 自定义依赖属性
  2. (二)在.net中如何使用Memcached
  3. Win7下telnet使用
  4. Magicodes.IE 2.3重磅发布——.NET Core开源导入导出库
  5. 基于E18-2G4U04B的ZigBee3.0无线数据抓包安装方法
  6. 理发店管理系统java_美容美发店管理系统的设计与实现(JSP,SQLServer)(含录像)
  7. 廖雪峰讲python高阶函数求导公式_高阶函数 - 廖雪峰 Python 2.7 中文教程
  8. python读取excel写入mysql_使用Python读Excel数据Insert到MySQL
  9. WebAssembly 介绍
  10. 17 行为型模式-----迭代器模式
  11. 火狐浏览器 附件组件 Xpath 安装
  12. 计算机abcd地址,IP地址ABCDE的分类说明
  13. 基于Java的愤怒的小鸟游戏的设计与实现
  14. JAVA测试人员考核_自动化测试的绩效考核
  15. 【慕伏白教程】Git的安装与基本使用
  16. 聊天的技巧,你是怎样和别人聊天的
  17. Hexo博客安装卡在“INFO install dependencies”解决方法
  18. 如何改域的NETBIOS名?
  19. SQL难学吗,有什么好的学习建议?(转载)
  20. L2-1 盲盒包装流水线 (25 分)

热门文章

  1. linux安装minikube(Ubuntu/deepin)
  2. Linux命令:dd、iostat、sar
  3. JVM调优:使用G1垃圾回收器
  4. ThreadPoolExecutor的七个参数详解
  5. 解决逆向工程mapper映射文件不发布问题
  6. Oracle实现数据增删改的sql语句实例
  7. Java-使用JavaMail发送一封邮件给用户邮箱功能实现
  8. oracle独立事务,Oracle中独立事务的处理
  9. Android基础——四大组件之Activity
  10. c语言菜单程序循环结构举例,C语言程序设计课件 第4章 循环结构.ppt