问题A: 集合删数
问题描述:
一个集合有如下元素:1是集合元素;若P是集合的元素,则2 * P +1,4*P+5也是集合的元素,取出此集合中最小的K个元素,按从小到大的顺序组合成一个多位数,现要求从中删除M个数位上的数字,使得剩下的数字最大,编程输出删除前和删除后的多位数字。
注:不存在所有数被删除的情况
输入格式:
输入的仅一行,K,M的值,K,M均小于等于30000。
输出格式:
输出为两行,第一行为删除前的数字,第二行为删除后的数字。
样例输入:
5 4
样例输出:
137915
95
program number; var k,m,tot,p1,p2,sum,i,j,t1,t2:longint; a:array[0..100010]of longint; p,q:ansistring; s:string; c:char; begin assign(input,'number.in');reset(input); assign(output,'number.out');rewrite(output); readln(k,m); a[1]:=1; p1:=1; p2:=1; for i:=2 to k do begin t1:=a[p1]*2+1; t2:=a[p2]*4+5; if t1=t2 then begin inc(p1);inc(p2);a[i]:=t1;end; if t1<t2 then begin inc(p1);a[i]:=t1;end; if t1>t2 then begin inc(p2);a[i]:=t2;end; end; p:=''; for i:=1 to k do begin str(a[i],s); p:=p+s; end; writeln(p); k:=length(p); p1:=0;tot:=0;q:=''; repeat inc(tot); c:='0'; for i:=p1+1 to tot+m do if c<p[i] then begin c:=p[i];p1:=i;end; q:=q+c; until tot=k-m; writeln(q); close(input);close(output); end.
问题B: d-规则问题
问题描述:
对任意给定的m(m∈N+)和n(n∈N+),满足m<n,构造一初始集合:P={x|m≤x≤n,x∈N+}(m,n≤100)。现定义一种d规则如下:若存在a∈P,且存在K∈N+ ,K>1,使得K´a∈P,则修改P为:P=P-{y|y=s´a,s∈N+ } ,并称该d规则具有分值a。现要求编制一个程序,对输入的m,n值,构造相应的初始集合P,对P每应用一次d规则就累加其相应的分值,求能得到最大累加分值的d规则序列,输出每次使用d规则时的分值和集合p的变化过程。
输入格式:
输入仅一行,M,N的值。
输出格式:
输出每次使用d规则时的分值和集合p的变化过程(即变化后的集合内所有的数,每个数用空格隔开),注意D后面有个空格,冒号后面有个空格。如果没有一次可以变化就输出0。
样例输入:
(1)
1 10
(2)
56 57
样例输出:
(1)
5 :1 2 3 4 6 7 8 9
4 :1 2 3 6 7 9
2 :1 3 7 9
3 :1 7
1 :
(2)
0
program drule; var p:set of byte; i,a,k,n,m,j,l:longint; flag:boolean; function get:longint; var i,k,l,num,ans:longint; begin ans:=maxlongint; num:=0; for i:=n div 2 downto 1 do if i in p then begin k:=1;l:=0; while true do begin if k*i>n then break; if k*i in p then inc(l); inc(k); end; if (l>1)and(l<ans) then begin ans:=l;num:=i;end; end; exit(num); end; begin assign(input,'drule.in');reset(input); assign(output,'drule.out');rewrite(output); readln(m,n); for i:=m to n do p:=p+[i]; l:=2; a:=get; j:=0; while true do begin if (a=0) then break; k:=1; if (j=0)and(not (a in p)) then break; while (a*k<=n) do begin if a*k in p then p:=p-[a*k]; inc(k); end; write(a,' : '); for i:=m to n do if i in p then write(i,' '); writeln; a:=get; inc(j); flag:=true; end; if not flag then writeln(0); close(input);close(output); end.
问题C: 极值问题
问题描述:
已知m、n为整数,且满足下列两个条件:
① m、n∈1,2,…,K,(1≤K≤10^9)
② (n^ 2-mn-m^2)^2=1
编一程序,对给定K,求一组满足上述两个条件的m、n,并且使m^2+n^2的值最大。例如,若K=1995,则m=987,n=1597,则m、n满足条件,且可使m^2+n^2的值最大。
输入格式:
输入仅一行,K的值。
输出格式:
输出仅一行,m^2+n^2的值
样例输入:
1995
样例输出:
3524578
#include<fstream> #include<cstdlib> #include<cstring> using namespace std; ifstream cin("maxf.in"); ofstream cout("maxf.out"); long long n; long long a[3][3],b[3][3],c[3][3]; long long num1,num2; int main() { int i,j,k; cin>>n; a[1][1]=1; a[1][2]=1; a[2][1]=1; a[2][2]=0; memcpy(b,a,sizeof(a)); while (b[1][1]+b[2][1]<n) { memset(c,0,sizeof(c)); for (i=1;i<3;i++) for (j=1;j<3;j++) for (k=1;k<3;k++) c[i][j]=c[i][j]+a[i][k]*b[k][j]; memcpy(b,c,sizeof(c)); } num1=b[1][1]; num2=b[2][1]; num1*=num1; num2*=num2; cout<<num1+num2<<endl; return 0; }
问题D: 所罗门王的藏宝图
问题描述:
亨利男爵,约翰上校和勇敢的猎象人夸特曼又一次在绝代佳人弗拉塔的帮助下破解了所罗门王藏宝洞的按钮密码,紧闭的藏宝洞门缓缓打开.三位寻宝英雄迫不及待地冲进藏宝洞.他们完全被展现在眼前的无数奇珍异宝惊呆了.在他们还没有回过神的时候藏宝洞门又自动关闭了,藏宝洞内变得一片漆黑.藉着宝石发出的荧光他们隐约看到紧闭的洞门边有一串若隐若现的数字.面对突如其来的变故约翰上校和夸特曼的脸上露出了惊恐的神色,而亨利男爵却是气定神闲胸有成竹的样子.原来亨利男爵在开始寻宝前就熟读寻宝秘籍,早已掌握了所罗门王藏宝洞的出门密码的奥秘.根据洞门边显现的数字,用寻宝秘籍上记录的神秘方式输入与其相应的密码就可以再次打开洞门.如何获取与洞门边显现的数字对应的密码?这还得从数百年前流行的一个移棋游戏说起.
棋盘上有若干方格排成一行,每个方格中可放1枚棋子.移棋游戏的规则是任意一枚棋子可以沿水平方向跳过与其相邻的棋子进入空着的方格并吃掉被跳过的棋子.其他方式的棋子移动都不是合法移动.对于棋盘上若干棋子的初始布局,如果存在一种合法着法使得最终棋盘上只剩下1枚棋子,则称这种布局为一个完美布局.例如图4中3枚棋子的布局是一个完美布局,移动2步后棋盘上只剩下1枚棋子.用棋盘上最左端棋子开始到最右端棋子结束的方格状态表示棋盘的初始布局,可将图4中的初始布局表示为1101.其中1表示棋子,0表示空格.在棋盘上有3枚棋子的所有布局中,只有1101和1011这2种布局是完美布局,其他的布局都不是完美布局.例如对于棋盘布局111就无法通过合法移动使得棋盘上最终只剩下1枚棋子.
如果藏宝洞门边显现的数字是n,那么与其对应的出门密码就是在棋盘上有n枚棋子时移棋游戏的完美布局数.试设计一个计算出门密码的算法,即计算移棋游戏的完美布局数.
输入格式:
由文件Treasure.in提供输入数据,文件的第一行中有1个正整数n,表示藏宝洞门边显现的数字,即移棋游戏的棋盘初始布局中有n枚棋子,0<n<15536.
输出格式:
将计算出的藏宝洞出门密码,即棋盘上有n枚棋子时移棋游戏的完美布局数输出到文件Treasure.out中.
样例输入:
3
样例输出:
2
#include<fstream> using namespace std; ifstream cin("treasure.in"); ofstream cout("treasure.out"); int i,j,k,n,sum; int main() { cin>>n; if (n==1||n==2) {cout<<1<<endl;return 0;} if (n==3) {cout<<2<<endl;return 0;} sum=3; i=4; while (i<n) { sum+=3+(((i-4)>>1)<<2); i++; } cout<<sum<<endl; return 0; }