2020-11-21
標題 找子串
題目: 計算字串中子串出現的次數。
要求:用一個子函式substring()實現,引數為指向字串和要查詢的子串的指標,返回次數。
#include<stdio.h>
int substring(char str1[],char str2[])
{
int sum=0;
char *p,*q;
p=str1;
q=str2;
while(*p!=’\0’)
{
if(*p==*q)
{
while(*p==*q&&*q!=’\0’)
{
p++;
q++;
}
}
else
p++;
if(q==’\0’)
sum++;
q=str2;
}
return sum;
}
int main(void)
{
char a[20],b[20];
scanf("%s%s",a,b);
printf("%d",substring(a,b));
return 0;
}
**剛開始寫的時候給substring函式的形參放的是兩個字元指標,就說值傳不進去,下邊實參對應的是兩個陣列的首地址,實參和形參要相互對應,不然會報錯。
通過指標的加減來對應字串和子串中的每一個字元來判斷子串出現的次數,子串出現’\0’就再迴圈重新判斷一次。字串到\0就跳出迴圈,返回次數sum。函式有返回值時主函式要有printf才能輸出返回值
標題 圍圈數數
題目:有n個人圍成一圈,順序排號。從第1個人開始報數(從1到3報數),凡是報到3的人退出圈子。
問最後留下的是原來第幾號的那位。
#include<stdio.h>
int main(void)
{
int n;
scanf("%d",&n);//先輸入人數
int a[n+1],i,k,t=0;
k=n;
for(i=1;i<=n;i++)
{
a[i]=1;//有人代表是1
}
for(i=1;;i++)//驚奇的發現判斷的限制條件可以不寫;不過後面必須有break,不然死迴圈
{
if(in+1)//轉過一圈後從第一個人重新開始數
i=1;
if(a[i]!=0)
t++;
else
continue;
if(t%30)
{
a[i]=0;
k–;
}
if(k==1)
break;//跳出迴圈
}
for(i=1;i<=n;i++)
{
if(a[i]!=0)
printf("%d",i);
}
return 0;
}
上面的continue用的十分精髓,它是跳出本次迴圈,進入下次迴圈。不然如果t剛好等於3的時候下一個a[i]也剛好等於0.t不加一,下面的if語句又會進去,下面的k會多減,最終剩下陣列中有1的不止一個,會輸出好多個人。
標題 數的轉移
題目:有n個整數。使其前面各各數順序向後移m個位置,最後m個數變成最前面的m個數。
要求:用函式,且原本的順序不變。
#include<stdio.h>
int move(int a,int n,int m)//這塊用a和a[]都可以,好像表示同一個意思,貌似發現了新大陸
{
int t[100],i;
for(i=0;i<n;i++)
{
t[i]=a[i];//先把原陣列中的數值傳到t陣列中,用兩個陣列,方便轉移。
}
for(i=0;i<m;i++)
{
a[i]=t[n-m+i];//把a陣列後面第n-m個及到後面最後一個的全部轉移到a陣列中第一個到第m-1個
}
for(i=m;i<n;i++)
{
a[i]=t[i-m];把a陣列第1個到第m個的值賦給a陣列第m個到最後一個
}
}
int main(void)
{
int n,m,i,a[20];
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
move(a,n,m);
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
標題 比大小
題目:比較三個數字的大小
要求:必須使用指標和函式
#include<stdio.h>
void swap(inta,intb)
{
int p;
p=*a;
*a=*b;
*b=p;
}
int main(void)
{
int z,x,c;
scanf("%d%d%d",&z,&x,&c);
if(z<x)
swap(&z,&x);
if(z<c)
swap(&z,&c);
if(x<c)
swap(&x,&c);
printf("%d %d %d",z,x,c);
return 0;
}
這道題本身不怎麼難,但是它主要考察的是函式值交換的問題,在函式中直接用變數交換,傳到主函式中變數本身的值還是不會交換。用指標就可以解決這一問題。
標題 數字的插入
題目:有一個已經排好序的陣列。現輸入一個數,要求按原來的規律將他插入陣列中。
要求:首先判斷此數是否大於最後一個數,然後再考慮插入中間的數的情況,插入此元素之後的數,依次後移一個位置。
#include<stdio.h>
int main(void)
{
int a[11]={1,4,6,9,13,16,19,28,40,100},k,t,end,j,i,p;//注意,是有序陣列
scanf("%d",&k);
end=a[9];
if(end<k)
a[10]=k;
else
{
for(i=0;i<9;i++)//從第一個數開始判斷,如果k小於,就把那個陣列中的值取出來賦給t,把k值放進去
{
if(a[i]>k)
{
t=a[i];
a[i]=k;
for(j=i+1;j<11;j++)
{
p=a[j];//把下一個陣列中的值取出來賦給p
a[j]=t;//把前一個陣列中的值給後一個陣列
t=p;//靈魂所在,把這個陣列的值給t,進行下一個陣列的值的交換,不斷迴圈下去
}
break;
}
}
}
for(i=0;i<11;i++)
{
printf("%d ",a[i]);
}
return 0;
}
這個題的思想類似於插入排序,先和最後一個作比較,比最後一個大直接放到a[10]這個空間中,
標題 下面這些題都是邏輯問題
題目:有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13…求出這個數列的前20項之和。
#include<stdio.h>
int main(void)
{
float s=0,a=2,b=1,t;
int i;
for(i=1;i<=20;i++)
{
s=s+a/b;
t=a;
a=a+b;
b=t;
}
printf("%f",s);
return 0;
}
這個主要考了下思想,邏輯問題,下一個分數的分子,是上一個分子分母的和,下一個分數的分母,等於上一個分數的分子。
題目:一球從100m高度自由落下,每次落地後反跳回原高度的一半;再落下,求它在第10次落地時,共經過多少m?第十次反彈多高?
#include<stdio.h>
int main(void)
{
float a,h=100.0,s=h/2;
int i;
for(i=1;i<10;i++)
{
h=h+2*s;
s=s/2;
}
printf("總共%f米。\n",h);
printf("第十次%f高。",s);
return 0;
}
當時記這道題的時候,感覺這道題還有點那味兒,現在看起來,挺簡單的,主要是邏輯問題,先求和算總高度,第十次彈起算第11次的高度。
加粗樣式
題目:猴子吃桃問題,猴子第一天摘下若干個桃子,當即吃了一半,還不過癮,又多吃了一個,第二天早上又將又將又吃掉剩下桃子的一半,又多吃一個,以後每天早上都吃了前一天剩下的一半零一個,到第10天早上想再吃時,見只剩下一個桃子了,問第一天共摘多少?
#include<stdio.h>
int main(void)
{
int day=9,x1=1,x2;//x1是最後一天剩餘的桃,
while(day>0)
{
x2=(x1+1)*2;//算出x1的前一天的桃數,
x1=x2;//這一行是關鍵,x1對應倒數第二天,最後迴圈到第一天;
day–;
}
printf("%d",x1);
return 0;
}
這道題考了逆向思維,留這,算是一種思想;
標題 一些程式碼題的判斷
** int d= -4;
unsigned e=2;
if(c<e)
printf("ok \n ");
else
printf(“no”)
這道題輸出的是no,int的負四比無符號的2大,這個我到現在其實也不是很懂,感覺是計算機算的時候,二進位制轉成補碼,無符號第一位是大小,而int型第一位表示的是符號,無符號是0到255的話,有符號是-128到127,算的時候出現了某些變化,等啥時候搞懂了再記,先在這留個底
**#include <stdio.h>
#define X(x) x;x;x;x;x;x;x;x;x;x;
int main(void)
{
int x = 1;
X(X(printf("%d ", x++)));
return 0;
}
這程式碼我也是看的馬馬虎虎,感覺有遞迴那味了,先記下它的計算邏輯,等以後變強了再回過頭看。
加粗樣式
int main(void)
{
int a = 0X7FFFFFFF;
if(a+1 > a)
{
printf(“ok \n”);
else
{
printf(“no \n”);
}
a+1溢位上限了,從a=2147483647,加一之後轉一圈到-2147483648最小值。
加粗樣式
int b =20;
float c =19.9;
if(b-c == 0.1)
{
printf(“ok \n”);
}
else
{
printf(“no \n”);
}
輸出的是no實數減浮點數20-19.9=0,原因不知,先當個結論記下,
但要注意的是,整型除浮點型除出來是浮點型
標題 偉大的雞兔同籠
雞兔共30只,腳共90個,編寫一個程式,求雞、兔各多少隻
#include<stdio.h>
int main(void)
{
int sum=30,jiao=90,ji,tu,k,t;
tu=(jiao-sum*2)/2;
ji=sum-tu;
printf(“ji=%d\ntu=%d\n”,ji,tu);
return 0;
}
常規方法就是用迴圈然後加if語句從1開始判斷,直到相等,就可得出結果程式碼找不到了,就在這不放了
下面說下我比較邪惡的方法,即我上面這串程式碼,把兔子每隻砍兩隻腳就和雞每隻的腿數一樣,用總腳減去雞兔總數乘以2,剩下的就是砍去的兔子的腳,除以二就是兔子的個數。
加粗樣式
#include<stdio.h>
int main(void)
{
int a[5];
printf("%p\n", a);
printf("%p\n", a+1);
printf("%p\n",&a);
printf("%p\n", &a+2);
printf("%p\n", &a+1);
return 0;
}
第一個輸出的是a陣列的首地址
第二個輸出的是a[1]的地址
第三個是把a的首地址取出來輸出的也是a的首地址
第四個 是把整個陣列取出來,步長是整個陣列,
a和&a指向的是同一塊地址,但他們+1後的效果不同,a+1是一個元素的記憶體大小(增加4),而&a+1增加的是整個陣列的記憶體
大小(增加40)。既a和&a的指向和&a[0]是相同的,但性質不同!
這段程式碼會輸出整個陣列的記憶體大小,而不是首元素的大小,由此我們是否聯絡到,sizeof(a)這裡的a和
&a有些相同之處呢?! 是的,沒錯,&a取都得是整個陣列的地址!既陣列名取地址等價於對陣列取地址。
其實a和 &a結果都是陣列的首地址,但他們的型別是不一樣。
a表示&a[0],也即對陣列首元素取地址,a+1表示首地址+sizeof(元素型別)。
&a雖然值為陣列首元素地址,但型別為:型別 (*)[陣列元素個數],所以&a+1大小為:首地址+sizeof(a)。