01. 奖券数目
有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利。
虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的号码,主办单位请你计算一下,如果任何两张奖券不重号,最多可发出奖券多少张。请提交该数字(一个整数),不要写任何多余的内容或说明性文字。
答案:52488
无脑解法:就是每个数逐位排除
#include <iostream>
using namespace std;
int main()
{
long long a = 10000;
long long ans = 0;
for (int i = a; i <= 99999; i++)
{
a = i; //这个很重要,不要忘了
int gewei = a%10;
if (gewei != 4)
{
a = a/10;
int shiwei = a%10;
if (shiwei != 4)
{
a = a/10;
int baiwei = a%10;
if (baiwei != 4)
{
a = a/10;
int qianwei = a%10;
if (qianwei != 4)
{
a = a/10;
int wanwei = a%10;
if (wanwei != 4)
{
a = a/10;
if (a != 4)
{
ans++;
}
}
}
}
}
}
}
cout << ans << endl;
}
优化:用函数解决,把数字转为字符串(注:i2s这个函数要记住)
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void i2s(int num, string &str) //这个函数要会背
{
stringstream ss; //用到头文件<sstream>
ss << num;
ss >> str;
}
int main()
{
int ans = 0;
for (int i = 10000; i <= 99999; i++)
{
string s;
i2s(i,s);
if (s.find('4') == string::npos) //string:npos是个特殊值,说明查找没有匹配
{
ans++;
}
}
cout << ans << endl;
return 0;
}
02. 星系炸弹
在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。 每个炸弹都可以设定多少天之后爆炸。
比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸。
有一个贝塔炸弹,2014年11月9日放置,定时为1000天,请你计算它爆炸的准确日期。请填写该日期,格式为 yyyy-mm-dd 即4位年份2位月份2位日期。比如:2015-02-19
请严格按照格式书写。不能出现其它文字或符号。
答案:2017-08-05
解:拿代码来计算:
#include <iostream>
using namespace std;
int main()
{
int i = 21+31; //2014年剩下的时间
i += 365; //2015年
i += 366; //2016年
// i += 365; //先尝试加完整个2017年,输出1148,超过一千了,所以在2017年爆炸,下面逐月加下去
// i += 31+28+31+30+31+30+31+31; //尝试加到8月,再输出,得到1026,所以说明在8月份
i += 31+28+31+30+31+30+31+5; //31-26=5 ,所以尝试+5,输出检查,结果正好为1000,所以就是在5号
cout << i << endl;
return 0;
}
03. 三羊献瑞
观察下面的加法算式:
祥 瑞 生 辉
+ 三 羊 献 瑞
-------------------
三 羊 生 瑞 气
(如果有对齐问题,可以参看【图1.jpg】)
其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。
请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。
答案:1085
无脑解法:
#include <iostream>
using namespace std;
int main()
{
int a,b,c,d,e,f,g,h;
for (a = 0; a <= 9; a++)
{
for (b = 0; b <= 9; b++)
{
if (b != a) //这一个注意不能漏,字不同,代表的数字也不能相同
{
for (c = 0; c <= 9; c++)
{
if (c!=a && c!=b)
{
for (d = 0; d <= 9; d++)
{
if (d!=a && d!= b && d!= c)
{
for (e = 0; e <= 9; e++)
{
if (e!=a && e!= b && e!= c && e!=d)
{
for (f = 0; f <= 9; f++)
{
if (f!=a && f!= b && f!= c && f!=d && f!=e)
{
for (g = 0; g <= 9; g++)
{
if (g!=a && g!= b && g!= c && g!=d && g!=e && g!=f)
{
for (h = 0; h <= 9; h++)
{
if (h!=a && h!= b && h!= c && h!=d && h!=e && h!=f && h!=g)
{
int i = e*1000 + d*100 + f*10 + g;
int j = a*1000 + b*100 + c*10 + d;
int k = a*10000 + b*1000 + f*100 + d*10 + h;
if((i+j) == k)
{
cout << a << " " << b << " " << c << " " << d << " " << e << " " << f << " " << g << " " << h << endl;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
输出:
因为是四位数,所以选“1085”
优化:
#include <iostream>
using namespace std;
int main()
{
for (int b = 2; b < 9; b++) //因为f=0,e=1,a=9,所以其它数不能是这三个数,这点要注意!!
{
for (int d = 2; d < 9; d++)
{
if (b == d)
{
continue;
}
for (int g = 2; g < 9; g++)
{
if (g == b || g == d)
{
continue;
}
int c = b+1;
if (c == b || c == d || c== g || c==9)
{
continue;
}
if (c+g <= 10)
{
continue;
}
int sum = 9000 + b*100 + c*10 + d + 1000 + g*10 + b;
for (int h = 2; h < 9; h++)
{
if (h == b || h == d || h == c || h == g)
{
continue;
}
if (sum <= (10000+c*100+b*10+h) && sum >= (10000+c*100+b*10+h))
{
cout << "10" << g << b << endl;
}
}
}
}
}
return 0;
}
04. 格子中输出
StringInGrid函数会在一个指定大小的格子中打印指定的字符串。 要求字符串在水平、垂直两个方向上都居中。 如果字符串太长,就截断。
如果不能恰好居中,可以稍稍偏左或者偏上一点。下面的程序实现这个逻辑,请填写划线部分缺少的代码。
#include <stdio.h>
#include <string.h>
void StringInGrid(int width, int height, const char* s)
{
int i,k;
char buf[1000];
strcpy(buf, s);
if(strlen(s)>width-2) buf[width-2]=0;
printf("+");
for(i=0;i<width-2;i++) printf("-");
printf("+\n");
for(k=1; k<(height-1)/2;k++){
printf("|");
for(i=0;i<width-2;i++) printf(" ");
printf("|\n");
}
printf("|");
printf("%*s%s%*s",_____________________________________________); //填空
printf("|\n");
for(k=(height-1)/2+1; k<height-1; k++){
printf("|");
for(i=0;i<width-2;i++) printf(" ");
printf("|\n");
}
printf("+");
for(i=0;i<width-2;i++) printf("-");
printf("+\n");
}
int main()
{
StringInGrid(20,6,"abcd1234");
return 0;
}
对于题目中数据,应该输出:
(如果出现对齐问题,参看下图所示)
注意:只填写缺少的内容,不要书写任何题面已有代码或说明性文字。
思路:
先把横线的那一行注释掉,然后运行一遍,看需要我们补充输出的是什么,再进行分析
答案:(width-strlen(buf)-2)/2," “,buf,(width-strlen(buf)-2)/2,” "
分析:考点就是%*
完整代码:
#include <stdio.h>
#include <string.h>
void StringInGrid(int width, int height, const char* s)
{
int i,k;
char buf[1000];
strcpy(buf, s);
if(strlen(s)>width-2) buf[width-2]=0; //如果字符串太长,就截断
printf("+");
for(i=0;i<width-2;i++) printf("-");
printf("+\n"); //输出第一条横边
for(k=1; k<(height-1)/2;k++){
printf("|"); //左边竖线的上半部分
for(i=0;i<width-2;i++) printf(" "); //中间的空格
printf("|\n"); //右边竖线的上半部分
} //这里就是解决上半空白部分
printf("|");
// printf("%*s%s%*s",_____________________________________________); //填空
// *号代表的是宽度,宽度表示有两种方式,一是直接填数字,二是用*号表示,
//*号可表示占位符,具体*号表示占多少,在外面写,例如printf("%*s\n",5,'1'); 空格到第五个的时候才输出字符串1
//由此可推出,横线上填的是字符串和字符串前后的空格数
printf("%*s%s%*s",(width-strlen(buf)-2)/2," ",buf,(width-strlen(buf)-2)/2," ");
//*号代表(width-strlen(buf)-2)/2," "代表*后面的s
printf("|\n");
for(k=(height-1)/2+1; k<height-1; k++){
printf("|");
for(i=0;i<width-2;i++) printf(" ");
printf("|\n");
}
printf("+");
for(i=0;i<width-2;i++) printf("-");
printf("+\n");
}
int main()
{
StringInGrid(20,6,"abcd1234");
return 0;
}
05. 九数组分数
1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法?
下面的程序实现了该功能,请填写划线部分缺失的代码。
#include <stdio.h>
void test(int x[]) {
int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
if(a*3==b) printf("%d / %d\n", a, b); }
void f(int x[], int k) {
int i,t;
if(k>=9){
test(x);
return;
}
for(i=k; i<9; i++){
{t=x[k]; x[k]=x[i]; x[i]=t;}
f(x,k+1);
_____________________________________________ // 填空处
} }
int main() {
int x[] = {1,2,3,4,5,6,7,8,9};
f(x,0);
return 0; }
注意:只填写缺少的内容,不要书写任何题面已有代码或说明性文字。
分析:本题是典型的全排列,要记住!
答案:{t=x[k]; x[k]=x[i]; x[i]=t;}
#include <stdio.h>
void test(int x[])
{
int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
if(a*3==b) printf("%d / %d\n", a, b);
} //检验x[]
void f(int x[], int k) //这个要会背,递归框架,全排列
{
int i,t;
if(k>=9){ //形成一个排列
test(x); //检查
return;
} //出口
for(i=k; i<9; i++){ //从k开始,将后续所有的字符都尝试着换到i这个位置
{t=x[k]; x[k]=x[i]; x[i]=t;} //交换,确定这一位
f(x,k+1); //尝试下一位
// _____________________________________________ // 填空处
{t=x[k]; x[k]=x[i]; x[i]=t;} //回溯,使i++时回到初始状态(恢复到下探之前的状态)
} //递归
}
int main()
{
int x[] = {1,2,3,4,5,6,7,8,9};
f(x,0);
return 0;
}