哥德巴赫分解
哥德巴赫猜想认为:不小于4的偶数都可以表示为两个素数的和。
你不需要去证明这个定理,但可以通过计算机对有限数量的偶数进行分解,验证是否可行。
实际上,一般一个偶数会有多种不同的分解方案,我们关心包含较小素数的那个方案。
对于给定数值范围,我们想知道这些包含较小素数方案中最大的素数是多少。
比如,100以内,这个数是19,它由98的分解贡献。
你需要求的是10000以内,这个数是多少?
注意,需要提交的是一个整数,不要填写任何多余的内容(比如,说明性的文字)
答案:173
1 #include <bits/stdc++.h> 2 3 /** 4 @author:d g w 5 */ 6 using namespace std; 7 typedef long long LL ; 8 9 const int maxn=1e4; 10 11 int prime[maxn]; 12 int pnum; 13 int hashtable[maxn]={false}; 14 void f(){ 15 for(int i=2;i<maxn;i++){ 16 if(hashtable[i]==false){ 17 prime[pnum++]=i; 18 for(int j=i+i;j<maxn;j+=i){ 19 hashtable[j]=true; 20 } 21 } 22 } 23 } 24 25 int main() 26 { 27 f(); 28 for(int i=0;i<pnum;i++){ 29 cout<<prime[i]<<" "; 30 }cout<<endl; 31 int ans[maxn]={0},re=0;bool flag=true; 32 for(int i=6;i<=10000;i+=2){ 33 for(int j=2;j<=i/2;j++){ 34 if(hashtable[j]==false&&hashtable[i-j]==false){ 35 cout<<i<<"="<<j<<"+"<<i-j<<endl; 36 ans[re++]=min(j,i-j); 37 break; 38 } 39 } 40 } 41 int res=0; 42 for(int j=0;j<re;j++){ 43 res=max(res,ans[j]); 44 } 45 cout<<res; 46 system("pause"); 47 return 0; 48 }
- 比较容易出错的枚举算法,很多细节需要注意;
#include <bits/stdc++.h> /** @author:d g w */ using namespace std; typedef long long LL ; const int maxn=1e5; int prime[maxn]; int pnum; int hashtable[maxn]= {false}; void f() { for(int i=2; i<maxn; i++) { if(hashtable[i]==false) { prime[pnum++]=i; for(int j=i+i; j<maxn; j+=i) { hashtable[j]=true; } } } } int main() { f(); for(int i=0; i<pnum; i++) { cout<<prime[i]<<" "; } cout<<endl; int ans[100000]= {0},re=0; for(int i=6; i<=10000; i+=2) { bool flag=true; for(int j=0; prime[j]<200; j++)//200以内就够了,可以打印出来看看规律 { for(int k=j+1; prime[k]<10000; k++)//易错点 顶峰值必须相近 要保证有最小值另一个加数必须大 { if((prime[j]+prime[k])==i) { cout<<prime[j]<<"+"<<prime[k]<<endl; ans[re++]=min(prime[j],prime[k]); flag=false; } } if(flag==false)break; } } int res=0; for(int j=0; j<re; j++) { res=max(res,ans[j]); } cout<<res; system("pause"); return 0; }
标题:数字划分
w星球的长老交给小明一个任务:
1,2,3...16 这16个数字分为两组。
要求:
这两组数字的和相同,
并且,两组数字的平方和也相同,
并且,两组数字的立方和也相同。
请你利用计算机的强大搜索能力解决这个问题。
并提交1所在的那个分组的所有数字。
这些数字要从小到大排列,两个数字间用一个空格分开。
即类似:1 4 5 8 ... 这样的答案。
注意,只提交这一组数字,不要填写任何多余的内容。
----------------------------------------
笨笨有话说:
只要一个组的成员确定了,另一个组的成员也就确定了。枚举一个组的成员就可以了。
凭直觉,两个组的成员数目不会差太多吧。
歪歪有话说:
既然求 1 所在的那个组,那只要枚举剩余的成员就可以了。
貌似都是8个成员的可能性很大啊。
answer:1 4 5 8 9 10 15 16
1 #include <bits/stdc++.h> 2 /** 3 @author:d g w 4 */ 5 using namespace std; 6 typedef long long LL ; 7 8 const int maxn=1e5; 9 10 int prime[maxn]; 11 int pnum; 12 int hashtable[maxn]= {false}; 13 void f() 14 { 15 for(int i=2; i<maxn; i++) 16 { 17 if(hashtable[i]==false) 18 { 19 prime[pnum++]=i; 20 for(int j=i+i; j<maxn; j+=i) 21 { 22 hashtable[j]=true; 23 } 24 } 25 } 26 } 27 int a[16]={1,4,5,8,2,3,6,7,9,10,11,12,13,14,15,16}; 28 int main() 29 { int flag=true; 30 do{ 31 if(!flag)break; 32 //1 4 5 8 33 if(a[0]==1&&a[1]==4&&a[2]==5&&a[3]==8){ 34 int x=a[0]+a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]; 35 int y=a[8]+a[9]+a[10]+a[11]+a[12]+a[13]+a[14]+a[15]; 36 if(x==y){ 37 if((x*x)==(y*y)){ 38 if((x*x*x)==(y*y*y)){ 39 //a[0]+a[1]+[2]+a[3]+a[4]+a[5]+a[6]+a[7] 40 if(a[0]<a[1]&&a[1]<a[2]&&a[2]<a[3]&&a[3]<a[4]&&a[4]<a[5]&&a[5]<a[6]&&a[6]<a[7]){ 41 cout<<a[0]<<' '<<a[1]<<' '<<a[2]<<' '<<a[3]<<' '<<a[4]<<' '<<a[5]<<' '<<a[6]<<' '<<a[7]<<endl; 42 flag=false; 43 } 44 } 45 } 46 } 47 } 48 49 }while(next_permutation(a+4,a+16)); 50 system("pause"); 51 return 0; 52 }
标题:表达式计算
虽然我们学了许久的程序设计,但对于简单的四则混合运算式,如果让我们完全白手起家地编程来解析,还是有点棘手。
这里,我们简化一下问题,假设只有加法和乘法,并且没有括号来改变优先级。
再假设参加运算的都是正整数。
在这么多的限制条件下,表达式的解析似乎简单了许多。
下面的代码解决了这个问题。请仔细阅读源码,并填写划线部分缺少的代码。
#include <stdio.h> int f3(const char* s, int begin, int end) { int sum = 0; int i; for(i=begin; i<end; i++){ if(s[i]==' ') continue; sum = sum * 10 + (s[i]-'0'); } return sum; } int f2(const char* s, int begin, int end) { int p = begin; int pro = 1; while(1){ int p0 = p; while(p!=end && s[p]!='*') p++; pro *= _______________________________; //填空 if(p==end) break; p++; } printf("f2: pro=%d\n", pro); return pro; } int f(const char* s) { int p = 0; int sum = 0; while(1){ int p0 = p; while(s[p]!=0 && s[p]!='+') p++; sum += f2(s,p0,p); if(s[p]==0) break; p++; } return sum; } int main() { int x = f("12+18+5*4*3+10"); printf("%d\n", x); return 0; }
answer:f3(s,p0,p)
注意:只填写划线处缺少的内容,不要填写已有的代码或符号,也不要填写任何解释说明文字等。
标题: 小数第n位
我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数。
如果我们把有限小数的末尾加上无限多个0,它们就有了统一的形式。
本题的任务是:在上面的约定下,求整数除法小数点后的第n位开始的3位数。
输入:
一行三个整数:a b n,用空格分开。a是被除数,b是除数,n是所求的小数后位置(0<a,b,n<1000000000)
输出:
一行3位数字,表示:a除以b,小数后第n位开始的3位数字。
比如:
输入:
1 8 1 0.125
程序应该输出:
125
再比如:
输入:
1 8 3
程序应该输出:
500
再比如:
输入:
282866 999000 6
282866 999 6
程序应该输出:
914
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
----------------------------------------
笨笨有话说:
这个除法小学就会算啊,模拟手算除法的过程就可以了吧。
只是数有点大啊....
管它呢,能算多远算多远....
歪歪有话说:
如果我能确定循环节从哪里开始到哪里结束,再大的数不过就是与它取模的余数等价啊
#include <bits/stdc++.h> /** @author:d g w */ using namespace std; typedef long long LL ; const int maxn=1e3; LL MOD=1e9+7; LL P=1e7+19; int main() { stringstream ss; string str,str2; LL a,b,n; cin>>a>>b>>n; cout<<setprecision(12)<<(double)a/b<<endl; ss<<setprecision(12)<<(double)a/b; ss>>str; int j=0; cout<<str<<endl; for(int i=n+1;i<str.length();i++){ str2[j++]=str[i]; } if(j==1){ cout<<str2[0]<<"00"; }else{ for(int i=0;i<j&&i<3;i++){ cout<<str2[i]; } } system("pause"); return 0; }
扑克牌
给定4张扑克牌 点数为:1~10
用+ - * / 运算,3个运算符结果正好为24
#include <bits/stdc++.h> /** @author:d g w */ using namespace std; typedef long long LL ; const int maxn=1e3; LL MOD=1e9+7; LL P=1e7+19; const int N=1e5; char rand_op(){ int x=rand()%4; if(x==0)return '+'; if(x==1)return '-'; if(x==3)return '*'; return '/'; } char op(int a,int b,char opr){ if(opr=='+')return (a+b)+'0'; if(opr=='*')return (a*b)+'0'; if(opr=='-')return (a-b)+'0'; if(a%b!=0) return 'n'; return a/b; } bool ji_suan(char buf[]){ stack<char> stk; for(int i=0;i<7;i++){ if(buf[i]=='+'||buf[i]=='-'||buf[i]=='*'||buf[i]=='/'){ int a=stk.top()-'0';stk.pop(); int b=stk.top()-'0';stk.pop(); if(op(a,b,buf[i])=='n'){ return false; }else{ stk.push(op(a,b,buf[i])); } }else{ stk.push(buf[i]); } } if(stk.size()==1 && (stk.top()-'0')==24) return true; return false; } void show(char buf[]){ stack<char> stk; for(int i=0;i<7;i++){ if(buf[i]=='+'||buf[i]=='-'||buf[i]=='*'||buf[i]=='/'){ int a=stk.top()-'0';stk.pop(); int b=stk.top()-'0';stk.pop(); if(op(a,b,buf[i])=='n'){ //return false; }else{ stk.push('('+stk.top()+buf[i]+stk.top()+')'); } }else{ stk.push(buf[i]); } } cout<<stk.top(); } void f(char str[]){ for(int z=0;z<1e4;z++){ char buf[7]; for(int i=0;i<4;i++)buf[i]==str[i]; for(int i=4;i<7;i++)buf[i]==rand_op(); random_shuffle(buf,buf+7); if(ji_suan(buf)){ show(buf); } } } int main() { srand((unsigned)time(NULL)); char s[4]; while(1){ cout<<"input number 4"<<endl; for(int i=0;i<4;i++){ cin>>s[i]; } f(s); } system("pause"); return 0; }