1.标题:武功秘籍
小明到X山洞探险,捡到一本有破损的武功秘籍(2000多页!当然是伪造的)。他注意到:书的第10页和第11页在同一张纸上,但第11页和第12页不在同一张纸上。
小明只想练习该书的第81页到第92页的武功,又不想带着整本书。请问他至少要撕下多少张纸带走?
这是个整数,请通过浏览器提交该数字,不要填写任何多余的内容。
答案:7
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
int cnt;
cnt=0;
for(int i=10; i<=92; i+=2) {
cnt++;
cout<<i<<' '<<i+1<<' '<<cnt<<endl;
}
return 0;
}
2.标题:等额本金
小明从银行贷款3万元。约定分24个月,以等额本金方式还款。
这种还款方式就是把贷款额度等分到24个月。每个月除了要还固定的本金外,还要还贷款余额在一个月中产生的利息。
假设月利率是:0.005,即:千分之五。那么,
第一个月,小明要还本金 1250, 还要还利息:30000 * 0.005,总计 1400.00
第二个月,本金仍然要还 1250, 但利息为:(30000-1250) * 0.005 总计 1393.75
请问:小明在第15个月,应该还款多少(本金和利息的总和)?请把答案金额四舍五入后,保留两位小数。注意:32.5,一定要写为:32.50
通过浏览器提交答案,这是一个含有小数点和两位小数的浮点数字。不要写多余内容(例如:多写了“元”或添加说明文字)
答案:1312.50
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
double li,ben=1250;
for(int i=0;i<24;i++){
li=0.005*(30000-ben*i);
printf("%d %.2f\n",i+1,li+ben);
}
return 0;
}
3.标题:猜年龄
小明带两个妹妹参加元宵灯会。别人问她们多大了,她们调皮地说:“我们俩的年龄之积是年龄之和的6倍”。小明又补充说:“她们可不是双胞胎,年龄差肯定也不超过8岁啊。”
请你写出:小明的较小的妹妹的年龄。注意: 只写一个人的年龄数字,请通过浏览器提交答案。不要书写任何多余的内容。
答案:10
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
for(int i=1;i<=100;i++){
for(int j=1;j<=100;j++){
if(i!=j&&abs(i-j)<=8&&i*j==6*(i+j)) cout<<i<<' '<<j<<endl;
}
}
return 0;
}
4.标题:大衍数列
中国古代文献中,曾记载过“大衍数列”, 主要用于解释中国传统文化中的太极衍生原理。
它的前几项是:0、2、4、8、12、18、24、32、40、50 ...
其规律是:对偶数项,是序号平方再除2,奇数项,是序号平方减1再除2。
以下的代码打印出了大衍数列的前 100 项。int main()
{
int i;
for(i=1; i<100; i++){
if(i%2==0) //填空
printf("%d ", i*i/2);
else
printf("%d ", (i*i-1)/2);
}
printf("\n");
}请填写划线部分缺失的代码。通过浏览器提交答案。
注意:不要填写题面已有的内容,也不要填写任何说明、解释文字。
5.标题:锦标赛
如果要在n个数据中挑选出第一大和第二大的数据(要求输出数据所在位置和值),使用什么方法比较的次数最少?我们可以从体育锦标赛中受到启发。
如图【1.png】所示,8个选手的锦标赛,先两两捉对比拼,淘汰一半。优胜者再两两比拼...直到决出第一名。
第一名输出后,只要对黄色标示的位置重新比赛即可。
下面的代码实现了这个算法(假设数据中没有相同值)。
代码中需要用一个数组来表示图中的树(注意,这是个满二叉树,不足需要补齐)。它不是存储数据本身,而是存储了数据的下标。
第一个数据输出后,它所在的位置被标识为-1
//本题思路类似于间接寻址的堆排序,输出第一大和第二大的数,即原数据不动,用各个数据的 index 进行堆排序,对于元素数据类型较大的情况下,用 index 进行间接寻址排序的话,可以减少很多数据的搬移,效率相对的要高。这里是用 b[]记录元素的index , a[]记录原始数据。
//重新决出k号位置,v为已输出值
void pk(int* a, int* b, int n, int k, int v)
{
int k1 = k*2 + 1;
int k2 = k1 + 1;
if(k1>=n || k2>=n){
b[k] = -1;
return;
}
if(b[k1]==v)
pk(a,b,n,k1,v);
else
pk(a,b,n,k2,v);
//重新比较
if(b[k1]<0){
if(b[k2]>=0)
b[k] = b[k2];
else
b[k] = -1;
return;
}
if(b[k2]<0){
if(b[k1]>=0)
b[k] = b[k1];
else
b[k] = -1;
return;
}
if(a[b[k1]]>a[b[k2]]) //填空 //比较b[k1]与b[k2]所对应的值谁更大
b[k] = b[k1];
else
b[k] = b[k2];
}//对a中数据,输出最大,次大元素位置和值
void f(int* a, int len)
{
int n = 1;
while(n<len) n *= 2; //建立完全二叉树——下标范围
int* b = (int*)malloc(sizeof(int*) * (2*n-1)); //分配存放二叉树的数组空间
int i;
for(i=0; i<n; i++){
if(i<len)
b[n-1+i] = i;
else
b[n-1+i] = -1;
}
//从最后一个向前处理 //建大顶堆
for(i=2*n-1-1; i>0; i-=2){
if(b[i]<0){
if(b[i-1]>=0)
b[(i-1)/2] = b[i-1];
else
b[(i-1)/2] = -1;
}
else{
if(a[b[i]]>a[b[i-1]])
b[(i-1)/2] = b[i];
else
b[(i-1)/2] = b[i-1];
}
}
//输出树根
printf("%d : %d\n", b[0], a[b[0]]); //输出分别为最大元素下标、最大元素的值
//值等于根元素的需要重新pk
pk(a,b,2*n-1,0,b[0]);
//再次输出树根
printf("%d : %d\n", b[0], a[b[0]]); //输出分别为次大元素下标、次大元素的值
free(b);
}
int main()
{
int a[] = {54,55,18,16,122,17,30,9,58};
f(a,9);
}请仔细分析流程,填写缺失的代码。
通过浏览器提交答案,只填写缺失的代码,不要填写已有代码或其它说明语句等。读题很重要!想想你做完题后分析的头头是道的样子,那才是你在考场上应该有的姿态。
6.标题:猜字母
把abcd...s共19个字母组成的序列重复拼接106次,得到长度为2014的串。
接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。
得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。
答案是一个小写字母,请通过浏览器提交答案。不要填写任何多余的内容。
答案:q
转化为留下偶数个字母
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int main (){
int n=106;
string str,s="abcdefghijklmnopqrs",tmp;
while(n--) str+=s;
while(str.size()!=1){
tmp="";
for(int i=1;i<str.size();i+=2)
tmp+=str[i]; //str.replace(i,1," "); (错误,因为size实时更新!)
str=tmp;
}
cout<<str;
return 0;
}
7.标题:扑克序列
A A 2 2 3 3 4 4, 一共4对扑克牌。请你把它们排成一行。
要求:两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌。
请填写出所有符合要求的排列中,字典序最小的那个。例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。
请通过浏览器提交答案。“A”一定不要用小写字母a,也不要用“1”代替。字符间一定不要留空格。
//2342A3A4
//'2'、'3'、'4'、'A'的ASC码依次为50,51,52,65
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int num[5];
bool judge(int a[]){
memset(num,-1,sizeof num);
for(int i=0;i<8;i++){
if(num[a[i]]!=-1) //存放上一个a[i]的位置,可能为0,故初始化为-1
num[a[i]]=abs(i-num[a[i]]-1);
else
num[a[i]]=i;
}
for(int i=1;i<=4;i++)
if(num[i]!=i) return false;
return true;
}
int main(){
int a[8]={2,2,3,3,4,4,1,1}; //在这里用1代替A
do{
if(judge(a)){
for(int i=0;i<8;i++)
cout<<a[i];
cout<<endl;
}
}while(next_permutation(a,a+8));
}
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int a[9]={0,1,1,2,2,3,3,4,4};
int num[5];
bool judge(){
memset(num,0,sizeof num);
for(int i=1;i<=8;i++){
if(num[a[i]]!=0) num[a[i]]=abs(i-num[a[i]])-1;
else num[a[i]]=i;
}
for(int i=1;i<=4;i++)
if(num[i]!=i) return false;
return true;
}
int main(){
do{
if(judge()){
for(int i=1;i<=8;i++)
cout<<a[i];
cout<<endl;
}
}while(next_permutation(a+1,a+9));
return 0;
}
8.标题:分糖果
有n个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏:
每个小朋友都把自己的糖果分一半给左手边的孩子。
一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数。
反复进行这个游戏,直到所有小朋友的糖果数都相同为止。
你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。
【格式要求】
程序首先读入一个整数N(2<N<100),表示小朋友的人数。
接着是一行用空格分开的N个偶数(每个偶数不大于1000,不小于2)
要求程序输出一个整数,表示老师需要补发的糖果数。
例如:输入
3
2 2 4
程序应该输出:
4资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int n;
int a[105];
int judge(){
int x=a[1];
for(int i=2;i<=n;i++)
if(a[i]!=x) return 0;
return 1;
}
int main () {
int ans=0,tmp;
cin>>n;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
while(judge()==0) {
tmp=a[1]/2; //防数据遗失
for(int i=1;i<n;i++){
a[i]=a[i]/2+a[i+1]/2;
if(a[i]%2){
a[i]++;
ans++;
}
}
a[n]=a[n]/2+tmp;
if(a[n]%2){
a[n]++;
ans++;
}
}
cout<<ans;
return 0;
}
9.标题:斐波那契斐波那契数列大家都非常熟悉。它的定义是:
f(x) = 1 .... (x=1,2)
f(x) = f(x-1) + f(x-2) .... (x>2)对于给定的整数 n 和 m,我们希望求出:
f(1) + f(2) + ... + f(n) 的值。但这个值可能非常大,所以我们把它对 f(m) 取模。
公式参见【图1.png】但这个数字依然很大,所以需要再对 p 求模。
【数据格式】
输入为一行用空格分开的整数 n m p (0 < n, m, p < 10^18)
输出为1个整数例如,如果输入:
2 3 5
程序应该输出:
0再例如,输入:
15 11 29
程序应该输出:
25资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
四十分代码,待更新……
#include<iostream>
#include<vector>
#define ll long long
using namespace std;
vector<long long> v;
ll n,m,p,tmp,sum=0;
void init() {
tmp=max(n,m);
v.push_back(0);
v.push_back(1);
v.push_back(1);
for(int i=3; i<=tmp; i++)
v.push_back(v[i-1]+v[i-2]);
}
int main() {
cin>>n>>m>>p;
init();
for(int i=1; i<=n; i++) {
sum=(sum+v[i])%v[m];
}
sum=sum%p;
cout<<sum<<endl;
return 0;
}
10.标题:矩阵翻硬币
小明先把硬币摆成了一个 n 行 m 列的矩阵。
随后,小明对每一个硬币分别进行一次 Q 操作。
对第x行第y列的硬币进行 Q 操作的定义:将所有第 i*x 行,第 j*y 列的硬币进行翻转。
其中i和j为任意使操作可行的正整数,行号和列号都是从1开始。
当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹——所有硬币均为正面朝上。
小明想知道最开始有多少枚硬币是反面朝上的。于是,他向他的好朋友小M寻求帮助。
聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的状态。然而小明很懒,不愿意照做。于是小明希望你给出他更好的方法。帮他计算出答案。【数据格式】
输入数据包含一行,两个正整数 n m,含义见题目描述。
输出一个正整数,表示最开始有多少枚硬币是反面朝上的。【样例输入】
2 3【样例输出】
1【数据规模】
对于10%的数据,n、m <= 10^3;
对于20%的数据,n、m <= 10^7;
对于40%的数据,n、m <= 10^15;
对于10%的数据,n、m <= 10^1000(10的1000次方)。资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
以下解析摘自网络,后文附有原文链接
1.很容易得出,如果一枚硬币被翻了奇数次,那么它原来的状态肯定是反面朝上,所以,我们要找的就是被翻了奇数次的硬币
2. 根据Q操作定义,我们举个例子,对于(2,3)这个点只有在(1,1)(1,3)(2,1)(2,3)这四个点进行Q操作时才翻转,一共翻转了4次,通过多个例子总结不难看出,(x,y)点再所有点进行完Q操作后翻转的次数为a*b次,其中a为x的约数,b为y的约数。因此若想要这个硬币被翻奇数次,a和b必须都得是奇数,即x和y都有奇数个约数。
先普及一个数论知识:完全平方数有奇数个约数。
那个这个问题就转化成了——输入两个数n,m,设小于等于n的完全平方数的个数是a,小于等于m的完全平方数的个数是b,求a*b。那么怎么求小于等于n和m完全平方数的个数呢?
再普及一个知识:
那么这个题目有转化成了——输入两个数n,m,求[sqrt(n)]*[sqrt(m)]。
这样题目就简单很多了,只要解决两个问题就可以
1.大数的乘法
2.大数的平方根取整
问题1解决方法:
先弄两个代表数值的字符串s1,s2,将s1的每一位与s2相乘,存到一个整形数组里
举个例子s1=“123”,s2=“89”
123*89
规律:将s1[i]*s2[j]存入num[i+j+1]中,因为num[0]要存最后进位;存完后,对num数组进行倒着计算,比如27实际上就是123*89计算中3*9=27,即把7留下2进上去
最后结果就是10947
问题2解决方法:
这个开方方法不是我想出来的,是参照了大神的一个方法
假如一个数有偶数位n,那么这个数的方根有n/2位;如果n为奇数,那么方根为(n+1)/2位。
然后,让我们实际看一个例子,我们假设这个数就是1200
1.很明显,它有4位,所以它的方根有2位,然后,我们通过下面的方法来枚举出它的整数根
00*00=0<1200
10*10=100<1200
20*20=400<1200
30*30=900<1200
40*40=1600>1200
所以,这个根的十位就是3,然后,再枚举个位
31*31=961<1200
32*32=1024<1200
33*33=1089<1200
34*34=1156<1200
所以,这个根就是34,因为平方增长的速度还是比较快的,所以速度没有太大问题。为了提高速度,我们可以优化比较函数:
还拿上面的例子来说
30*30=900<1200
40*40=1600>1200
这两个式子,一般来说,我们应该先计算3*3=9,然后在9后面添2个0再与1200比较,但由于数据量很大,添零也会消耗时间
于是我们可以计算需要加的0的数量然后用下面的方法直接比较
1.如果第i个数的平方的位数加上需要添加的零的个数之后位数与原数不相等,那么位数大的数值大
2.如果位数相等就没必要再添零,直接进行字符串比较即可
例如:
30*30=900<1200
40*40=1600>1200
十位是3的时候 3*3=9是1位填上两个零后位数位3位小于1200的4位所以900<1200
十位是4的时候 4*4=16是两位,添上两个零后位数为4位等于1200的四位,所以只需比较字符串16与1200的大小
很明显在字符串中16>1200,所以1600>1200
那么添加零的个数怎么算呢?
假设一个数的平方根取整的位数为n,从前往后算目前计算到了第i位,则需要添加2*(n-1-i)个零
例如:1200 平方根取整有2位,目前算到了第0位(从0开始计数)即30*30(我们算的是3*3),需要加2*(2-1-0)=2个零
原文:https://blog.csdn.net/reidsc/article/details/64924051
#include <iostream>
#include <algorithm>
using namespace std;
string StrMul(string s1,string s2) { //大数乘法
string ans;
int num[500]= {0},i,j;
for(i=0; i<s1.length(); i++) //s计算存到num中
for(j=0; j<s2.length(); j++)
num[i+j+1]+=(s1[i]-'0')*(s2[j]-'0');
for(i=s1.length()+s2.length()-1; i>0; i--) //num的处理
if(num[i]>=10) {
num[i-1]+=num[i]/10;
num[i]%=10;
}
for(int i=0; i<=s1.length()+s2.length()-1; i++) //将num数存到ans字串中,注意进位为0的情况
if(!i&&num[i]||i)
ans.push_back(num[i]+'0');
return ans;
}
bool StrCmp(string s1,string s2,int pos) { //比较两字符串大小,pos代表应该在s1后面填几个零
if(s1.length()+pos!=s2.length())//如果s1位数不等于s2,
return s1.length()+pos>s2.length();
else//位数相等
return s1>s2;
}
string SqrtStr(string s) { //大数平方根取整
int len;
string ans;
if(s.length()%2==0)//长度为偶数
len=s.length()/2;
else
len=s.length()/2+1;
for(int i=0; i<len; i++) { //一位一位的循环
ans.push_back('0');
for(int j=0; j<=9; j++) {
if(StrCmp(StrMul(ans,ans),s,2*(len-1-i)))//需要添加0的个数是2*(len-1-i)解析见上面
break;
ans[i]++;
}
ans[i]--;
}
return ans;
}
int main() {
string s1,s2;
cin>>s1>>s2;
cout<<StrMul(SqrtStr(s1),SqrtStr(s2))<<endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int num[505];
void BigMul(string s1,string s2){
int len1=s1.size();
int len2=s2.size();
for(int i=0;i<len1;i++)
for(int j=0;j<len2;j++)
num[i+j+1]+=(s1[i]-'0')*(s2[j]-'0');
for(int i=len1+len2-1;i>0;i--){//范围0~len1+len2-1
if(num[i]>=10){
num[i-1]+=num[i]/10;
num[i]%=10;
}
}
string ans;
for(int i=0;i<=len1+len2-1;i++)
if(!i&&num[i]||i) ans.push_back(num[i]+'0');
cout<<ans;
}
int main(){
string s1,s2;
cin>>s1>>s2;
BigMul(s1,s2);
return 0;
}