1. 标题:啤酒和饮料
啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。
我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。
思路
简简单单 for循环加判断
但有个小技巧就是将每个数扩大十倍
这样运算速度快了很多。
#include<stdio.h>
int main()
{
int a,b,c,sum=0;
int cnt2=0,cnt1=0;
a=19,b=23;
for(int k=1;k<=100;k++)
{
for(int k1=1;k1<=100;k1++)
{
sum=b*k+a*k1;
if(sum==823)
{
printf("%d %d",k,k1);
return 0;
}
else if(sum>823)
break;
}
}
}
两者时间差。
2.标题:切面条
一根高筋拉面,中间切一刀,可以得到2根面条。
如果先对折1次,中间切一刀,可以得到3根面条。
如果连续对折2次,中间切一刀,可以得到5根面条。
那么,连续对折10次,中间切一刀,会得到多少面条呢?
思路
这题找到规律非常简单。
后一次是前一次的2倍减一。
这数据这么小 very nice。
#include<stdio.h>
int main()
{
int a[20];
a[1]=2;
a[2]=3;
for(int k=3;k<=15;k++)
{
a[k]=2*a[k-1]-1;
}
printf("%d",a[11]);
return 0;
}
3.标题:李白打酒
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数。
思路
1.递归了解一下。
2.全排列了解一下。(想偷懒没写了)
要么进店酒乘2,
要么见花酒减1,
14番后剩一口,
#include<stdio.h>
int a=2,cnt;
void dfs(int jiu,int step,int dian,int hua)
{
if(step==14)
{
if(jiu==1&&dian==5&&hua==9)
cnt++;
}
if(dian<=5&&hua<=9)
{
dfs(2*jiu,step+1,dian+1,hua);
dfs(jiu-1,step+1,dian,hua+1);
}
}
int main()
{
dfs(a,0,0,0);
printf("%d",cnt);
return 0;
}
4.标题:史丰收速算
史丰收速算法的革命性贡献是:从高位算起,预测进位。不需要九九表,彻底颠覆了传统手算!
速算的核心基础是:1位数乘以多位数的乘法。
其中,乘以7是最复杂的,就以它为例。
因为,1/7 是个循环小数:0.142857…,如果多位数超过 142857…,就要进1
同理,2/7, 3/7, … 6/7 也都是类似的循环小数,多位数超过 n/7,就要进n
下面的程序模拟了史丰收速算法中乘以7的运算过程。
乘以 7 的个位规律是:偶数乘以2,奇数乘以2再加5,都只取个位。
乘以 7 的进位规律是:
满 142857… 进1,
满 285714… 进2,
满 428571… 进3,
满 571428… 进4,
满 714285… 进5,
满 857142… 进6
请分析程序流程,填写划线部分缺少的代码。
nt ge_wei(int a)
{
if(a % 2 == 0)
return (a * 2) % 10;
else
return (a * 2 + 5) % 10;
}
//计算进位
int jin_wei(char* p)
{
char* level[] = {
"142857",
"285714",
"428571",
"571428",
"714285",
"857142"
};
char buf[7];
buf[6] = '\0';
strncpy(buf,p,6);
int i;
for(i=5; i>=0; i--){
int r = strcmp(level[i], buf);
if(r<0) return i+1;
while(r==0){
p += 6;
strncpy(buf,p,6);
r = strcmp(level[i], buf);
if(r<0) return i+1;
______________________________; //填空
}
}
return 0;
}
//多位数乘以7
void f(char* s)
{
int head = jin_wei(s);
if(head > 0) printf("%d", head);
char* p = s;
while(*p){
int a = (*p-'0');
int x = (ge_wei(a) + jin_wei(p+1)) % 10;
printf("%d",x);
p++;
}
printf("\n");
}
int main()
{
f("428571428571");
f("34553834937543");
return 0;
}
答案
if(r>0)return i
5.标题:打印图形
小明在X星球的城堡中发现了如下图形和文字:
rank=3
*
* *
* *
* * * *
rank=5
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
ran=6
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
小明开动脑筋,编写了如下的程序,实现该图形的打印。
#define N 70
void f(char a[][N], int rank, int row, int col)
{
if(rank==1){
a[row][col] = '*';
return;
}
int w = 1;
int i;
for(i=0; i<rank-1; i++) w *= 2;
____________________________________________;
f(a, rank-1, row+w/2, col);
f(a, rank-1, row+w/2, col+w);
}
int main()
{
char a[N][N];
int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++) a[i][j] = ' ';
f(a,6,0,0);
for(i=0; i<N; i++){
for(j=0; j<N; j++) printf("%c",a[i][j]);
printf("\n");
}
return 0;
}
请仔细分析程序逻辑,填写缺失代码部分。
答案
f(a, rank-1, row, col+w/2);
6.标题:奇怪的分式
上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:
1/4 乘以 8/5
小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png)
老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!
对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢?
请写出所有不同算式的个数(包括题中举例的)。
显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。
但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!
思路
for循环选数,if判断,__gcd(函数输入两个int类型数返回两者最小公约数)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int sum=0,m,n;
for(int k=1;k<=9;k++)
{
for(int k1=1;k1<=9;k1++)
{
for(int k2=1;k2<=9;k2++)
{
for(int k3=1;k3<=9;k3++)
{
if(k!=k2&&k1!=k3)
{
m=__gcd(k*k1,k2*k3);
n=__gcd(k*10+k1,k2*10+k3);
if((k*k1)/m==(k*10+k1)/n&&(k2*k3)/m==(k2*10+k3)/n)
{
printf("%d %d %d %d\n",k,k1,k2,k3);
sum++;
}
}
}
}
}
}
printf("%d",sum);
return 0;
}
7.标题:六角填数
使得每条直线上的数字之和都相同。
图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少。
思路
dfs搜索每一个格子要选什么数
注意一点:遇到原本填好的点记得跳过
要不然你填不完数递归就结束了,
因为你遇到填过的节点你不能dfs(step+1);
#include<stdio.h>
int a[12],book[12],sum[10];
void dfs(int step)
{
if(step==10||step==11)
dfs(step+1);
if(step==12)
{
sum[1]=a[0]+a[1]+a[2]+a[3];
sum[2]=a[3]+a[4]+a[5]+a[6];
sum[3]=a[6]+a[7]+a[8]+a[0];
sum[4]=a[1]+a[8]+a[9]+a[10];
sum[5]=a[11]+a[5]+a[7]+a[9];
sum[6]=a[10]+a[2]+a[4]+a[11];
for(int k=1;k<=6;k++)
{
if(sum[1]!=sum[k])
return;
}
printf("%d\n",a[2]);
return;
}
for(int k=1;k<=12;k++)
{
if(book[k]==0)
{
a[step]=k;
book[k]=1;
dfs(step+1);
book[k]=0;
}
}
}
int main()
{
a[0]=1,book[1]=1;
a[10]=8,book[8]=1;
a[11]=3,book[3]=1;
dfs(1);
return 0;
}
8.蚂蚁感冒
长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。
每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。
当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
【数据格式】
第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。
接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。
要求输出1个整数,表示最后感冒蚂蚁的数目。
例如,输入:
3
5 -2 8
程序应输出:
1
再例如,输入:
5
-10 8 -20 12 25
程序应输出:
3
思路
首先蚂蚁正前方的头朝向不同的蚂蚁会中毒
如果没有就它自己中毒
否则在加上比它小的头朝向相同的蚂蚁
后加上它自己就是中毒的蚂蚁数目。
#include<stdio.h>
#include<math.h>
int n[60];
int main()
{
int a,b,c,sum1=0;
scanf("%d",&a);
for(int k=1;k<=a;k++)
{
scanf("%d",&n[k]);
}
if(n[1]<0)
{
for(int k=2;k<=a;k++)
if(n[k]>0&&n[k]<abs(n[1]))
sum1++;
if(sum1==0)
{
printf("1");
return 0;
}
for(int k=2;k<=a;k++)
if(n[k]<0&&n[k]<n[1])
sum1++;
printf("%d",sum1+1);
}
else
{
for(int k=2;k<=a;k++)
if(n[k]<0&&abs(n[k])>n[1])
sum1++;
if(sum1==0)
{
printf("1");
return 0;
}
for(int k=2;k<=a;k++)
if(n[k]>0&&n[k]<n[1])
sum1++;
printf("%d",sum1+1);
}
return 0;
}