部分题 所有题见链接
链接:https://pan.baidu.com/s/1gqmAgmnPQcZ48U5zjrGyUg
提取码:jpoz
T3 方格填数
如下的10个格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
(如果显示有问题,也可以参看【图1.jpg】)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
#include <iostream> #include <string> #include <sstream> #include <algorithm> #include <cstring> using namespace std ; int ans = 0; int check(int a[]){ if(a[0]-a[4]==-1||a[0]-a[4]==1) return 0; if(a[3]-a[4]==-1||a[3]-a[4]==1) return 0; if(a[5]-a[4]==-1||a[5]-a[4]==1) return 0; if(a[7]-a[4]==-1||a[7]-a[4]==1) return 0; if(a[8]-a[4]==-1||a[8]-a[4]==1) return 0; if(a[9]-a[4]==-1||a[9]-a[4]==1) return 0; if(a[1]-a[4]==-1||a[1]-a[4]==1) return 0; if(a[1]-a[5]==-1||a[1]-a[5]==1) return 0; if(a[1]-a[6]==-1||a[1]-a[6]==1) return 0; if(a[0]-a[5]==-1||a[0]-a[5]==1) return 0; if(a[2]-a[5]==-1||a[2]-a[5]==1) return 0; if(a[8]-a[5]==-1||a[8]-a[5]==1) return 0; if(a[9]-a[5]==-1||a[9]-a[5]==1) return 0; if(a[6]-a[5]==-1||a[6]-a[5]==1) return 0; if(a[6]-a[9]==-1||a[6]-a[9]==1) return 0; if(a[6]-a[2]==-1||a[6]-a[2]==1) return 0; if(a[3]-a[0]==-1||a[3]-a[0]==1) return 0; if(a[3]-a[7]==-1||a[3]-a[7]==1) return 0; if(a[8]-a[7]==-1||a[8]-a[7]==1) return 0; if(a[8]-a[3]==-1||a[8]-a[3]==1) return 0; if(a[9]-a[8]==-1||a[9]-a[8]==1) return 0; if(a[1]-a[0]==-1||a[1]-a[0]==1) return 0; if(a[1]-a[2]==-1||a[1]-a[2]==1) return 0; } //手动全排列 void f(int k ,int a[]){ //出口 if(k == 10){ if(check(a)!= 0 ){ ans++; } return ; } for(int i = k; i<10 ; ++i){ {int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //深入 f(k+1,a); {int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //回溯 } } void i2s(int x, string &basic_string) { stringstream ss; ss << x; ss >> basic_string; } void s2i(string &basic_string , int &x ) { stringstream ss; ss << basic_string; ss >> x; } void c2i(char &basic_string , int &x ) { stringstream ss; ss << basic_string; ss >> x; } void c2s(char c , string & s){ stringstream stream; stream << c; s = stream.str(); } //自动全排列 void f1(string s, int a[]){ do{ for(int i=0 ; i<10 ; ++i){ int temp ; // string temps ; // c2s (s[i],temps); // s2i(temps,temp); c2i(s[i],temp); a[i] = temp ; } check(a); }while(next_permutation(s.begin(),s.end())); } int main(){ //int a[10]={0,1,2,3,4,5,6,7,8,9}; //f(0,a); int a[10]; string s ="0123456789" ; f1(s,a); cout<<ans<<endl; }
T6 寒假作业
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □
(如果显示不出来,可以参见【图1.jpg】)
每个方块代表1~13中的某一个数字,但不能重复。
比如:
6 + 7 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
以及:
7 + 6 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
#include <iostream> #include <string> #include <sstream> #include <algorithm> #include <math.h> using namespace std ; int ans = 0; int check(int a[]){ bool b1 = (a[0]+a[1])==a[2] ; bool b2 = (a[3]-a[4])==a[5] ; bool b3 = (a[6]*a[7])==a[8] ; bool b4=(fabs((a[9]*1.0)/(a[10]*1.0)-a[11]*1.0)<=0.00000000000001); if(b1&&b2&&b3&&b4)return 1; return 0; } //手动全排列 void f(int k ,int a[]){ //出口 if(k==4){ if(a[0]+a[1] != a[2])return ; } if(k==7){ if(a[3]-a[4] != a[5])return ; } if(k==10){ if(a[6]*a[7] != a[8])return ; } if(k == 13){ if(check(a)==1){ ans++; for(int i = 0; i<13 ; ++i){ cout<<a[i]; }cout<<endl; } return ; } for(int i = k; i<13 ; ++i){ {int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //深入 f(k+1,a); {int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //回溯 } } int main (){ int a[13]={1,2,3,4,5,6,7,8,9,10,11,12,13}; f(0,a); cout<<ans<<endl; //64 }
T7 剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
#include <iostream> #include <string> #include <sstream> #include <algorithm> #include <math.h> using namespace std ; int ans = 0; int check1(int a[],int i){ switch (i){ case 0: if(a[1]>0 || a[4]>0)return 1; case 1: if(a[i-1]>0 || a[i+1]>0 || a[i+4]>0)return 1; case 2 : if(a[i-1]>0 || a[i+1]>0 || a[i+4]>0)return 1; case 3: if(a[2]>0 || a[7]>0)return 1; case 4: if(a[0]>0 || a[5>0] || a[8]>0)return 1; case 5: if(a[i-4]>0 || a[i-1]>0 || a[i+1]>0 || a[i+4]>0)return 1; case 6: if(a[i-4]>0 || a[i-1]>0 || a[i+1]>0 || a[i+4]>0)return 1; case 7: if(a[3]>0 || a[6]>0 || a[11]>0)return 1; case 8: if(a[4]>0 || a[9]>0 )return 1; case 9: if(a[i-1]>0 || a[i+1]>0 || a[i-4]>0)return 1; case 10: if(a[i-1]>0 || a[i+1]>0 || a[i-4]>0)return 1; case 11: if(a[7]>0 || a[10]>0 )return 1; default: return 0; } } int check(int a[]){ for(int i =0; i<12 ; ++i ){ if(a[i]==1){ if(check1(a,i)!=1) return 0; } } return 1; } void c2i(char &basic_string , int &x ) { stringstream ss; ss << basic_string; ss >> x; } //自动全排列 void f1(string s, int a[]){ do{ for(int i=0 ; i<12 ; ++i){ int temp ; c2i(s[i],temp); a[i] = temp ; } if(check(a)==1){ ans++; for(int i = 0; i<12 ; ++i){ cout<<a[i]; }cout<<endl; } }while(next_permutation(s.begin(),s.end())); } //手动全排列 void f(int k ,int a[]){ //出口 if(k == 12){ if(check(a)==1){ ans++; for(int i = 0; i<12 ; ++i){ cout<<a[i]; }cout<<endl; } return ; } for(int i = k; i<12 ; ++i){ {int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //深入 f(k+1,a); {int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //回溯 } } int main (){ //int a[12]={1,2,3,4,5,-1,-2,-3,-4,-5,-6,-7}; string s = "123400000005" ; int a[12]; f1(s,a); cout<<ans<<endl; }
T8 四平方和
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多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>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
#include <iostream> #include <math.h> #include <map> #include <cmath> #include <time.h> #include <stdio.h> using namespace std; map<int , int> cache; void f1(int n){ for(int c = 0 ; c*c<n/10 ;++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; } } } //a b找 void f2(int n){ for(int a =0;a*a<n/8;++a){ for(int b=a;a*a+b*b <n/4 ;++b){ if(cache.find(n-a*a-b*b)!=cache.end()){ //找到了符合的c d int c = cache[n-a*a-b*b] ; int d = sqrt(n-a*a-b*b-c*c); printf("%d %d %d %d ",a,b,c,d); return ; } } } } int main(){ long int n; cin>>n; // 使用clock()构造clock_t对象(实际上是long类型的变量) clock_t t1 = clock(); //缓存 f1(n); //找 f2(n); // 计算clock差,除以clock数/每秒,即可求出秒数 // 将秒数乘以1000得到毫秒数 cout << (clock() - t1) * 1.0 / CLOCKS_PER_SEC * 1000 << endl; return 0 ; }