目录
7-1 重要的话说三遍
这道题就是直接输出三次题目给出的字符串就行。
#include<stdio.h>
int main()
{
printf("I'm gonna WIN!\nI'm gonna WIN!\nI'm gonna WIN!\n");
return 0;
}
7-2 两小时学完C语言
这道题就是直接读入然后运算输出就行。
#include<stdio.h>
int main()
{
int n, k, m;
scanf("%d%d%d", &n, &k, &m);
printf("%d", n-(k*m));
return 0;
}
7-3 拯救外星人
这道题我用的是前缀和求阶乘的方法,感觉这个方法用来求阶乘确实是否方便快捷加轻松简单。
7-4 谁能进图书馆
这道题就是根据题目的一个模拟。
其有以下几种情况:
1.两人都大于或等于禁入年龄线,此时两人都可进入;
2.两人都小于禁入年龄线,此时两人都不可进入;
3.其中一个大于或等于陪同年龄线,另一个小于禁入年龄线,此时两人都可进入,但要注意谁是大于或等于的人,谁是小于的人;
4.其中一个大于或等于禁入年龄线但小于陪同年龄线,另一个小于禁入年龄线,此时前者可以进入,但后者不能进入;
然后分别根据这四种情况进行对应输出即可。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int a, b, c, d;
int c1=1;
int d2=2;
scanf("%d%d%d%d", &a, &b, &c, &d);
if(c>=a&&d>=a)
{
printf("%d-Y %d-Y\nhuan ying ru guan", c, d);
return 0;
}
if(c<a&&d<a)
{
printf("%d-N %d-N\nzhang da zai lai ba", c, d);
return 0;
}
int minx, maxx;
minx=min(c, d);
maxx=max(c, d);
if(maxx>=b&&minx<a)
{
if(c>d)
printf("%d-Y %d-Y\nqing %d zhao gu hao %d", c, d,c1, d2);
else
printf("%d-Y %d-Y\nqing %d zhao gu hao %d", c, d, d2, c1);
return 0;
}
if(maxx>=a&&maxx<b&&minx<a)
{
if(c>d)
printf("%d-Y %d-N\n%d: huan ying ru guan", c, d, c1);
else
printf("%d-N %d-Y\n%d: huan ying ru guan", c, d, d2);
return 0;
}
}
7-5 试试手气
这道题我一开始的想法是这样的:开一个二维的行和列都是6的数组,并为其赋从6到0递减的值,然后先把题目给出的那6个数所对应的数组中的位置改为0;
然后进行k-1次循环,每次循环就把每行的最大值(第一个非0的值)赋值为0;
第k次循环所取的每行的第一个非0的值即为所求答案。
#include<stdio.h>
int main()
{
int a[6][6]={
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1}
};
int n[6];
for(int i=0;i<6;i++)
{
scanf("%d", &n[i]);
}
for(int i=0;i<6;i++)
{
for(int j=0;j<6;j++)
{
if(a[i][j]==n[i])
{
a[i][j]=0;
break;
}
}
}
int k;
scanf("%d", &k);
for(int i=0;i<k-1;i++)
{
for(int o=0;o<6;o++)
{
for(int p=0;p<6;p++)
{
if(a[o][p]!=0)
{
a[o][p]=0;
break;
}
}
}
}
for(int o=0;o<6;o++)
{
for(int p=0;p<6;p++)
{
if(o==5)
{
if(a[o][p]!=0)
{
printf("%d\n", a[o][p]);
return 0;
}
}
if(a[o][p]!=0)
{
printf("%d ", a[o][p]);
break;
}
}
}
}
其实后面两部,那两次循环是没有必要的,合并为一个循环即可,其中用ai[]数组来记录每次循环后所对应的最大值组合。代码如下:
#include<stdio.h>
int main()
{
int a[6][6]={
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1},
{6, 5, 4, 3, 2, 1}
};
int n[6];
for(int i=0;i<6;i++)
{
scanf("%d", &n[i]);
}
for(int i=0;i<6;i++)
{
for(int j=0;j<6;j++)
{
if(a[i][j]==n[i])
{
a[i][j]=0;
break;
}
}
}
int k;
scanf("%d", &k);
int ai[6];
for(int i=0;i<k;i++)
{
for(int o=0;o<6;o++)
{
for(int p=0;p<6;p++)
{
if(a[o][p]!=0)
{
ai[o]=a[o][p];
a[o][p]=0;
break;
}
}
}
}
for(int i=0;i<6;i++)
{
if(i==5)
{
printf("%d\n", ai[i]);
return 0;
}
printf("%d ", ai[i]);
}
}
7-6 查验身份证
这道题一开始就是直接跟着题目写的,虽然过了,但代码非常的冗长。其实可以用打表的方式来优化一下代码,两段代码我都附在下面。
优化前代码:
#include<stdio.h>
int main()
{
int n;
scanf("%d", &n);
int k=0;
for(int i=0;i<n;i++)
{
char a[20];
scanf("%s", a);
long long s;
s=(a[0]-'0')*7+
(a[1]-'0')*9+
(a[2]-'0')*10+
(a[3]-'0')*5+
(a[4]-'0')*8+
(a[5]-'0')*4+
(a[6]-'0')*2+
(a[7]-'0')*1+
(a[8]-'0')*6+
(a[9]-'0')*3+
(a[10]-'0')*7+
(a[11]-'0')*9+
(a[12]-'0')*10+
(a[13]-'0')*5+
(a[14]-'0')*8+
(a[15]-'0')*4+
(a[16]-'0')*2;
s=s%11;
if(s==0)
{
if(a[17]!='1')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==1)
{
if(a[17]!='0')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==2)
{
if(a[17]!='X')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==3)
{
if(a[17]!='9')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==4)
{
if(a[17]!='8')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==5)
{
if(a[17]!='7')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==6)
{
if(a[17]!='6')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==7)
{
if(a[17]!='5')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==8)
{
if(a[17]!='4')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==9)
{
if(a[17]!='3')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
if(s==10)
{
if(a[17]!='2')
{
k=1;
printf("%s\n", a);
continue;
}
continue;
}
}
if(k==0)
printf("All passed");
return 0;
}
优化后代码:
#include<stdio.h>
char v[11]={'1','0','X','9','8','7','6','5','4','3','2'};
int main()
{
int n;
scanf("%d", &n);
int k=0;
for(int i=0;i<n;i++)
{
char a[20];
scanf("%s", a);
long long s;
s=(a[0]-'0')*7+
(a[1]-'0')*9+
(a[2]-'0')*10+
(a[3]-'0')*5+
(a[4]-'0')*8+
(a[5]-'0')*4+
(a[6]-'0')*2+
(a[7]-'0')*1+
(a[8]-'0')*6+
(a[9]-'0')*3+
(a[10]-'0')*7+
(a[11]-'0')*9+
(a[12]-'0')*10+
(a[13]-'0')*5+
(a[14]-'0')*8+
(a[15]-'0')*4+
(a[16]-'0')*2;
s=s%11;
if(v[s]!=a[17])
{
k=1;
printf("%s\n", a);
continue;
}
}
if(k==0)
printf("All passed");
return 0;
}
7-7 连续因子
这道题有两种思路,分别如下:
思路1:求出n的所有的因子,然后去找其中的最长的连续因子
#include<stdio.h>
#include<math.h>
int main()
{
long long n;
scanf("%lld", &n);
if(n==2)
{
printf("1\n2\n");
return 0;
}
int c=0;
for(int i=2;i<=(int)sqrt(n);i++)
{
if(n%i==0)
c=1;
}
if(c==0)
{
printf("1\n%lld\n", n);
return 0;
}
int xi=0;
int l=0;
long long s;
for(int i=2;i<=(int)sqrt(n);i++)
{
s=1;
for(int j=i;s*j<=n;j++)
{
s=s*j;
if(n%s==0&&j-i+1>l)
{
xi=i;
l=j-i+1;
}
}
}
printf("%d\n", l);
for(int i=xi;i<xi+l;i++)
{
if(i==xi+l-1)
{
printf("%d\n", i);
return 0;
}
printf("%d", i);
printf("*");
}
}
思路2:去找一个x,这个x是有几个连续的因子相乘得到的因子,只要这个x能被n整除,说明这个x是n的因子,找到组成x的最多的连续因子的个数。
由于13的阶乘以及大于了2的31次方,所以,组成x的连续个因子的个数最多为12个,又因为要求最长的连续因子个数,所以选择从12开始向1遍历。
#include<bits/stdc++.h>
int main()
{
long n;
scanf("%ld", &n);
long s;
for(int i=12;i>=1;i--)
{
for(int j=2;j<=(int)sqrt(n);j++)
{
s=1;
for(int k=0;k<i;k++)
{
s=s*(j+k);
}
if(s>n)
break;
if(n%s==0){
printf("%d\n", i);
for(int p=0;p<i;p++)
{
if(p==i-1)
{
printf("%d\n", j+i-1);
return 0;
}
printf("%d*", j+p);
}
}
}
}
printf("1\n%ld", n);
return 0;
}
7-8 出租
这道题的关键在与声明的两数组的对应关系。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int main()
{
char c[20];
scanf("%s", c);
int a[20];
int arr[10];
int index[12];
int l=strlen(c);
for(int i=0;i<l;i++)
{
a[i]=c[i]-'0';
}
int arri=0;
for(int i=0;i<l;)
{
if(i==0)
{
arr[arri]=a[i];
arri++;
}
else
{
for(int j=0;j<arri;j++)
{
if(a[i]==arr[j])
goto tiao;
}
arr[arri]=a[i];
arri++;
}
tiao:
i++;
}
sort(arr, arr+arri, greater<int>());
int indexi=0;
for(int i=0;i<l;i++)
{
for(int j=0;j<arri;j++)
{
if(a[i]==arr[j])
{
index[indexi]=j;
indexi++;
}
}
}
printf("int[] arr = new int[]{");
for(int i=0;i<arri;i++)
{
if(i==arri-1)
{
printf("%d", arr[i]);
break;
}
printf("%d,", arr[i]);
}
printf("};\nint[] index = new int[]{");
for(int i=0;i<indexi;i++)
{
if(i==indexi-1)
{
printf("%d", index[i]);
break;
}
printf("%d,", index[i]);
}
printf("};\n");
return 0;
}
7-10 列车厢调度
这道题我的思路是先看3轨道中有无元素,有则判断最后一个元素是否与2轨道中当前元素相同,相同则3轨道的长度减一,2轨道的当前元素后移一位,然后continue,若不是,则进行下面操作;
判断1轨道中的当前元素是否与2轨道的当前元素相同,是则两轨道的当前元素后移一位,否则1轨道的当前元素复制到3轨道中,3轨道长度加一,然后后移一位。
这里我选择用字符数组来表示轨道。
#include<stdio.h>
#include<string.h>
int cixu[1000000];
int xi=0;
int main()
{
char a[30];
char b[30];
scanf("%s", a);
scanf("%s", b);
//printf("%s\n", a);
//printf("%s\n", b);
char c[30];
int ci=0;
int l=strlen(a);
int j=0;
for(int i=0;i<l;)
{
int f=0;
if(ci!=0)
{
int xci=ci;
for(int o=0;o<xci;o++)
{
if(c[xci-1-o]==b[i])
{
cixu[xi]=3;//printf("3->2\n");
xi++;
i++;
f=1;
ci--;
//printf("1 %d %d %d\n", xi, ci, xci);
continue;
}
else
break;
}
}
if(j<l)
{
f++;
if(a[j]==b[i])
{
cixu[xi]=1;//printf("1->2\n");
xi++;
i++;
j++;
continue;
}
else
{
cixu[xi]=2;//printf("1->3\n");
xi++;
c[ci]=a[j];
ci++;
j++;
}
}
if(f==0)
{
printf("Are you kidding me?");
return 0;
}
}
for(int i=0;i<xi;i++)
{
if(cixu[i]==1)
{
printf("1->2\n");
}
if(cixu[i]==2)
{
printf("1->3\n");
}
if(cixu[i]==3)
{
printf("3->2\n");
}
}
return 0;
}