⑴ C語言開燈問題就解釋,題目什麼意思
//我覺得7號燈肯定是在關閉狀態
//因為第1個人把所有等打開,那麼只有第7個人是7的倍數,
//所以第7個人會把第7個燈關閉掉,7號燈的狀態肯定是關閉的
//所以說你這個輸出有可能是錯誤的。
//給你寫的完整代碼,希望能幫到你。
#include<stdio.h>
#defineN1000
structLight
{
intnum;
intonOff;//1打開0關閉
};
intmain()
{
intn,k,i;
Lightlight[N];
scanf("%d%d",&k,&n);
if(k>n||n>1000) //不符合條件的直接返回
return0;
for(i=0;i<N;i++)//初始化燈都是亮著的,因為第1個人會把所有燈打開
{
light[i].onOff=1;
light[i].num=i+1;
}
for(i=2;i<=k;i++)//從第2個人開始循環,一直到第k個
for(intj=0;j<n;j++)
if(light[j].num%i==0&&light[j].num>=i)//如果燈的編號是人的編號的倍數,且燈號大於人號
{
if(light[j].onOff==1)//如果是開,就關閉,否則打開
light[j].onOff=0;
elselight[j].onOff=1;
//輸出信息
printf("i=%d第%d號燈,狀態:%d ",i,light[j].num,light[j].onOff);
}
for(i=0;i<n;i++)//遍歷,輸出所有打開的燈
if(light[i].onOff==1)
printf("%d",light[i].num);
printf(" ");
return0;
}
⑵ 求助C語言中的開燈問題!有n盞燈 編號1~n 第一個人把所有燈點亮 ,第2個人按下所有編號為2的倍
這個是白皮書上的題吧。。
把數組a清零之後,每次 j%i==0 a[j] = !a[j];取反的意思就是把0變非零,非零變零。
0和非零,來模擬燈的狀態,0表示燈在關著,取非!之後表示燈在開著。
if(first)first = 0;就是為了滿足題意的輸出要求,書上寫的很清楚,如果是想要單純學演算法,不需要在意那些細節,掌握重要思路及代碼就行了;如果要比賽,這個就比較重要,需要謹慎。
if(first)就相當於if(first!=0)的意思。
還有什麼不懂的嗎?
⑶ 用c語言實現演算法led0亮2秒,led1亮3秒,led1滅2秒,led0滅5秒程序
貌似是考多線程,你這裡面沒說明同步規則,就分開寫吧:
void led0thread()
{
while(1)
{
led0.light();
Sleep(2000);
led0.turnoff();
Sleep(5000);
}
}
void led1thread()
{
while(1)
{
led0.light();
Sleep(3000);
led0.turnoff();
Sleep(2000);
}
}
⑷ 開燈問題用C語言怎麼解決
#include"stdio.h"
voidmain()
{
/*0表示關燈,1表示開燈*/
intn,k,a[101],i,b,c,d;
printf("輸入人數");
scanf("%d",&k);
printf("輸入燈的數目");
scanf("%d",&n);
for(i=1;i<101;i++)
{
a[i]=0;
}
for(b=1;b<=k;b++)//這里不能是k++啊!死循環了
{
for(c=1;c<=n;c++)
{
if(c%b==0)
{
if(a[c]==0)
{
a[c]=1;
}else
{
a[c]=0;
}
}
}
}
for(d=1;d<=n;d++)
if(a[d]==1){
printf("%d",d);//加上空格,看著清楚些
}
}
⑸ 大神們,求解一道演算法編程,最好只用C語言編寫,拜託啦= =
#include<stdio.h>
#include<stdlib.h>
intmain()
{intn,i,j,m,t,x,a[1000];
scanf("%d",&n);
a[0]=rand()%25;
printf("%d",a[0]);
for(i=1;i<n;i++)
{a[i]=a[i-1]+rand()%10+1;
printf("%d",a[i]);
}
printf("
x=");
scanf("%d",&x);
for(i=0,j=n-1;i<j;)
{m=(i+j)/2;
if(a[m]==x){j=m;break;}
elseif(a[m]<x)i=m+1;
elsej=m;
}
if(a[j]==x)
{t=a[j];a[j]=a[j+1];a[j+1]=t;}
else
{if(a[j]<x)j++;
for(i=n;i>j;i--)a[i]=a[i-1];
a[j]=x;
n++;
}
for(i=0;i<n;)
printf("%d",a[i++]);
printf("
");
return0;
}
⑹ C語言開燈問題,有n(n<100)盞燈,編號為1~n。第一個人把所有燈都打開,第二個人按下所有
看代碼比寫代碼麻煩,寫一個你作參考……
//#include"stdafx.h"//Ifthevc++6.0,withthisline.
#include"stdio.h"
intmain(void){
charlight[101];
intn,k,i,j;
while(1){
printf("Inputn&k(0<n<1000<k<=n)... n=");
if(scanf("%d%d",&n,&k)&&n>0&&n<100&&k>0&&k<=n)
break;
printf("Error,redo:");
}
for(i=1;i<=n;light[i++]=1);
for(i=2;i<=k;i++)
for(j=i;j<=n;j++)
if(j%i==0)
light[j]^=1;
for(i=1;i<=n;i++)
if(light[i])
printf("%d",i);
printf(" ");
return0;
}
⑺ 開燈問題用C語言中的數組怎麼解決
#include <stdio.h>
#define n 100
void main(void)
{
int i, j, a[n];
for(i = 0; i < n; i++) a[i] = 0;// 初始化為全0
for(i = 1; i <= n; i++)
for(j = i ; j <= n; j = j + i)
a[j - 1] += 1;
//100人對100燈,都操作完畢,下面是顯示
for(i = 0; i < n; i++) {
if((i % 8) == 0) printf("\n");
printf(" L%2d: %d, ", i + 1, a[i] % 2);
}
printf("\n");
}
/*
運行結果顯示如下:
L 1: 1, L 2: 0, L 3: 0, L 4: 1, L 5: 0, L 6: 0, L 7: 0, L 8: 0,
L 9: 1, L10: 0, L11: 0, L12: 0, L13: 0, L14: 0, L15: 0, L16: 1,
L17: 0, L18: 0, L19: 0, L20: 0, L21: 0, L22: 0, L23: 0, L24: 0,
L25: 1, L26: 0, L27: 0, L28: 0, L29: 0, L30: 0, L31: 0, L32: 0,
L33: 0, L34: 0, L35: 0, L36: 1, L37: 0, L38: 0, L39: 0, L40: 0,
L41: 0, L42: 0, L43: 0, L44: 0, L45: 0, L46: 0, L47: 0, L48: 0,
L49: 1, L50: 0, L51: 0, L52: 0, L53: 0, L54: 0, L55: 0, L56: 0,
L57: 0, L58: 0, L59: 0, L60: 0, L61: 0, L62: 0, L63: 0, L64: 1,
L65: 0, L66: 0, L67: 0, L68: 0, L69: 0, L70: 0, L71: 0, L72: 0,
L73: 0, L74: 0, L75: 0, L76: 0, L77: 0, L78: 0, L79: 0, L80: 0,
L81: 1, L82: 0, L83: 0, L84: 0, L85: 0, L86: 0, L87: 0, L88: 0,
L89: 0, L90: 0, L91: 0, L92: 0, L93: 0, L94: 0, L95: 0, L96: 0,
L97: 0, L98: 0, L99: 0, L100: 1,
Press any key to continue
*/
⑻ C語言的開燈問題,有短代碼不理解 求大神解答。
a[j]=!a[j]的意思是a[j]取原來值的邏輯反,比如原來為0,則取反後為1保存,原來如果是1,則運算後保存為0, 可以用a[j]=1-a[j];代替
⑼ 適合初學者的24點游戲C語言源代碼
關於二十四點游戲的編程思路與基本演算法
漫長的假期對於我來說總是枯燥無味的,閑來無聊便和同學玩起童年時經常玩的二十四點牌游戲來。此游戲說來簡單,就是利用加減乘除以及括弧將給出的四張牌組成一個值為24的表達式。但是其中卻不乏一些有趣的題目,這不,我們剛玩了一會兒,便遇到了一個難題——3、6、6、10(其實後來想想,這也不算是個太難的題,只是當時我們的腦筋都沒有轉彎而已,呵呵)。
問題既然出現了,我們當然要解決。冥思苦想之際,我的腦中掠過一絲念頭——何不編個程序來解決這個問題呢?文曲星中不就有這樣的程序嗎?所以這個想法應該是可行。想到這里我立刻開始思索這個程序的演算法,最先想到的自然是窮舉法(後來發現我再也想不到更好的方法了,悲哀呀,呵呵),因為在這學期我曾經寫過一個小程序——計算有括弧的簡單表達式。只要我能編程實現四個數加上運算符號所構成的表達式的窮舉,不就可以利用這個計算程序來完成這個計算二十四點的程序嗎?確定了這個思路之後,我開始想這個問題的細節。
首先窮舉的可行性問題。我把表達式如下分成三類——
1、 無括弧的簡單表達式。
2、 有一個括弧的簡單表達式。
3、 有兩個括弧的較復4、 雜表達式。
窮舉的開始我對給出的四個數進行排列,其可能的種數為4*3*2*1=24。我利用一個嵌套函數實現四個數的排列,演算法如下:
/* ans[] 用來存放各種排列組合的數組 */
/* c[] 存放四張牌的數組 */
/* k[] c[]種四張牌的代號,其中k[I]=I+1。
用它來代替c[]做處理,考慮到c[]中有可能出現相同數的情況 */
/* kans[] 暫存生成的排列組合 */
/* j 嵌套循環的次數 */
int fans(c,k,ans,kans,j)
int j,k[],c[];char ans[],kans[];
{ int i,p,q,r,h,flag,s[4],t[4][4];
for(p=0,q=0;p<4;p++)
{ for(r=0,flag=0;r if(k[p]!=kans[r]) flag++;
if(flag==j) t[j][q++]=k[p];
}
for(s[j]=0;s[j]<4-j;s[j]++)
{ kans[j]=t[j][s[j>;
if(j==3) { for(h=0;h<4;h++)
ans[2*h]=c[kans[h]-1]; /* 調整生成的排列組合在最終的表
達式中的位置 */
for(h=0;h<3;h++)
symbol(ans,h); /* 在表達式中添加運算符號 */
}
else { j++;
fans(c,k,ans,kans,j);
j--;
}
}
}
正如上面函數中提到的,在完成四張牌的排列之後,在表達式中添加運算符號。由於只有四張牌,所以只要添加三個運算符號就可以了。由於每一個運算符號可重復,所以計算出其可能的種數為4*4*4=64種。仍然利用嵌套函數實現添加運算符號的窮舉,演算法如下:
/* ans[],j同上。sy[]存放四個運算符號。h為表達式形式。*/
int sans(ans,sy,j,h)
char ans[],sy[];int j,h;
{ int i,p,k[3],m,n; char ktans[20];
for(k[j]=0;k[j]<4;k[j]++)
{ ans[2*j+1]=sy[k[j>; /* 剛才的四個數分別存放在0、2、4、6位
這里的三個運算符號分別存放在1、3、5位*/
if(j==2)
{ ans[5]=sy[k[j>;
/* 此處根據不同的表達式形式再進行相應的處理 */
}
else { j++; sans(ans,sy,j--,h); }
}
}
好了,接下來我再考慮不同表達式的處理。剛才我已經將表達式分為三類,是因為添加三個括弧對於四張牌來說肯定是重復的。對於第一種,無括弧自然不用另行處理;而第二種情況由以下代碼可以得出其可能性有六種,其中還有一種是多餘的。
for(m=0;m<=4;m+=2)
for(n=m+4;n<=8;n+=2)
這個for循環給出了添加一個括弧的可能性的種數,其中m、n分別為添加在表達式中的左右括弧的位置。我所說的多餘的是指m=0,n=8,也就是放在表達式的兩端。這真是多此一舉,呵呵!最後一種情況是添加兩個括弧,我分析了一下,發現只可能是這種形式才不會是重復的——(a b)(c d)。為什麼不會出現嵌套括弧的情況呢?因為如果是嵌套括弧,那麼外面的括弧肯定是包含三個數字的(四個沒有必要),也就是說這個括弧裡麵包含了兩個運算符號,而這兩個運算符號是被另外一個括弧隔開的。那麼如果這兩個運算符號是同一優先順序的,則肯定可以通過一些轉換去掉括弧(你不妨舉一些例子來試試),也就是說這一個括弧沒有必要;如果這兩個運算符號不是同一優先順序,也必然是這種形式((a+-b)*/c)。而*和/在這幾個運算符號中優先順序最高,自然就沒有必要在它的外面添加括弧了。
綜上所述,所有可能的表達式的種數為24*64*(1+6+1)=12288種。哈哈,只有一萬多種可能性(這其中還有重復),這對於電腦來說可是小case喲!所以,對於窮舉的可行性分析和實現也就完成了。
接下來的問題就是如何對有符號的簡單表達式進行處理。這是棧的一個著名應用,那麼什麼是棧呢?棧的概念是從日常生活中貨物在貨棧種的存取過程抽象出來的,即最後存放入棧的貨物(堆在靠出口處)先被提取出去,符合「先進後出,後進先出」的原則。這種結構猶如子彈夾。
在棧中,元素的插入稱為壓入(push)或入棧,元素的刪除稱為彈出(pop)或退棧。
棧的基本運算有三種,其中包括入棧運算、退棧運算以及讀棧頂元素,這些請參考相關數據結構資料。根據這些基本運算就可以用數組模擬出棧來。
那麼作為棧的著名應用,表達式的計算可以有兩種方法。
第一種方法——
首先建立兩個棧,操作數棧OVS和運算符棧OPS。其中,操作數棧用來記憶表達式中的操作數,其棧頂指針為topv,初始時為空,即topv=0;運算符棧用來記憶表達式中的運算符,其棧頂指針為topp,初始時,棧中只有一個表達式結束符,即topp=1,且OPS(1)=『;』。此處的『;』即表達式結束符。
然後自左至右的掃描待處理的表達式,並假設當前掃描到的符號為W,根據不同的符號W做如下不同的處理:
1、 若W為操作數
2、 則將W壓入操作數棧OVS
3、 且繼續掃描下一個字元
4、 若W為運算符
5、 則根據運算符的性質做相應的處理:
(1)、若運算符為左括弧或者運算符的優先順序大於運算符棧棧頂的運算符(即OPS(top)),則將運算符W壓入運算符棧OPS,並繼續掃描下一個字元。
(2)、若運算符W為表達式結束符『;』且運算符棧棧頂的運算符也為表達式結束符(即OPS(topp)=』;』),則處理過程結束,此時,操作數棧棧頂元素(即OVS(topv))即為表達式的值。
(3)、若運算符W為右括弧且運算符棧棧頂的運算符為左括弧(即OPS(topp)=』(『),則將左括弧從運算符棧談出,且繼續掃描下一個符號。
(4)、若運算符的右不大於運算符棧棧頂的運算符(即OPS(topp)),則從操作數棧OVS中彈出兩個操作數,設先後彈出的操作數為a、b,再從運算符棧OPS中彈出一個運算符,設為+,然後作運算a+b,並將運算結果壓入操作數棧OVS。本次的運算符下次將重新考慮。
第二種方法——
首先對表達式進行線性化,然後將線性表達式轉換成機器指令序列以便進行求值。
那麼什麼是表達式的線性化呢?人們所習慣的表達式的表達方法稱為中綴表示。中綴表示的特點是運算符位於運算對象的中間。但這種表示方式,有時必須藉助括弧才能將運算順序表達清楚,而且處理也比較復雜。
1929年,波蘭邏輯學家Lukasiewicz提出一種不用括弧的邏輯符號體系,後來人們稱之為波蘭表示法(Polish notation)。波蘭表達式的特點是運算符位於運算對象的後面,因此稱為後綴表示。在對波蘭表達式進行運算,嚴格按照自左至右的順序進行。下面給出一些表達式及其相應的波蘭表達式。
表達式 波蘭表達式
A-B AB-
(A-B)*C+D AB-C*D+
A*(B+C/D)-E*F ABCD/+*EF*-
(B+C)/(A-D) BC+AD-/
OK,所謂表達式的線性化是指將中綴表達的表達式轉化為波蘭表達式。對於每一個表達式,利用棧可以把表達式變換成波蘭表達式,也可以利用棧來計算波蘭表達式的值。
至於轉換和計算的過程和第一種方法大同小異,這里就不再贅述了。
下面給出轉換和計算的具體實現程序——
/* first函數給出各個運算符的優先順序,其中=為表達式結束符 */
int first(char c)
{ int p;
switch(c)
{ case '*': p=2; break;
case '/': p=2; break;
case '+': p=1; break;
case '-': p=1; break;
case '(': p=0; break;
case '=': p=-1; break;
}
return(p);
}
/* 此函數實現中綴到後綴的轉換 */
/* M的值宏定義為20 */
/* sp[]為表達式數組 */
int mid_last()
{ int i=0,j=0; char c,sm[M];
c=s[0]; sm[0]='='; top=0;
while(c!='\0')
{ if(islower(c)) sp[j++]=c;
else switch(c)
{ case '+':
case '-':
case '*':
case '/': while(first(c)<=first(sm[top]))
sp[j++]=sm[top--];
sm[++top]=c; break;
case '(': sm[++top]=c; break;
case ')': while(sm[top]!='(')
sp[j++]=sm[top--];
top--; break;
default :return(1);
}
c=s[++i];
}
while(top>0) sp[j++]=sm[top--];
sp[j]='\0'; return(0);
}
/* 由後綴表達式來計算表達式的值 */
int calc()
{ int i=0,sm[M],tr; char c;
c=sp[0]; top=-1;
while(c!='\0')
{ if(islower(c)) sm[++top]=ver[c-'a'];/*在轉換過程中用abcd等來代替數,
這樣才可以更方便的處理非一位數,
ver數組中存放著這些字母所代替的數*/
else switch(c)
{ case '+': tr=sm[top--]; sm[top]+=tr; break;
case '-': tr=sm[top--]; sm[top]-=tr; break;
case '*': tr=sm[top--]; sm[top]*=tr; break;
case '/': tr=sm[top--];sm[top]/=tr;break;
default : return(1);
}
c=sp[++i];
}
if(top>0) return(1);
else { result=sm[top]; return(0); }
}
這樣這個程序基本上就算解決了,回過頭來拿這個程序來算一算文章開始的那個問題。哈哈,算出來了,原來如此簡單——(6-3)*10-6=24。
最後我總結了一下這其中容易出錯的地方——
1、 排列的時候由於一個數只能出現一次, 所以必然有一個判斷語句。但是用什麼來判斷,用大小顯然不行,因為有可能這四個數中有兩個或者以上的數是相同的。我的方法是給每一個數設置一個代號,在排列結束時,通過這個代號找到這個數。
2、在應用嵌套函數時,需仔細分析程序的執行過程,並對個別變數進行適當的調整(如j的值),程序才能正確的執行。
3、在分析括弧問題的時候要認真仔細,不要錯過任何一個可能的機會,也要盡量使程序變得簡單一些。不過我的分析可能也有問題,還請高手指點。
4、在用函數對一個數組進行處理的時候,一定要注意如果這個數組還需要再應用,就必須將它先保存起來,否則會出錯,而且是很嚴重的錯誤。
5、在處理用戶輸入的表達式時,由於一個十位數或者更高位數是被分解成各位數存放在數組中,所以需對它們進行處理,將它們轉化成實際的整型變數。另外,在轉化過程中,用一個字母來代替這個數,並將這個數存在一個數組中,且它在數組中的位置和代替它的這個字母有一定的聯系,這樣才能取回這個數。
6、由於在窮舉過程難免會出現計算過程中有除以0的計算,所以我們必須對calc函數種對於除的運算加以處理,否則程序會因為出錯而退出(Divide by 0)。
7、最後一個問題,本程序尚未解決。對於一些比較著名的題目,本程序無法解答。比如說5、5、5、1或者8、8、3、3。這是由於這些題目在計算的過程用到了小數,而本程序並沒有考慮到小數。
⑽ 需要一個C語言程序。51單片機控制:按鍵按一下,延遲1分鍾後開燈,燈亮半個小時就熄滅的程序急需!
如果對時間要求不精確,用軟延時即可。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit s=P1^0;
sbit led=P1^1;
void delayms(uint i) //1ms延時程序
{
uchar j;
for(;i>0;i--)
{
for(j=0;j<125;j++)//如果延時時間誤差較大,可按比例改變125這個數
//取值范圍0-255,數值越大,延時越長
{;}
}
}
void delay1s(uint i) //1s延時程序
{
for(;i>0;i--){delay1ms(1000);}
}
void main()
{
led=0;
while(1)
{
if (s==0)
{
delayms(20);
if (s==0);{delay1s(60);led=1; }
}
if(led==1){delay1s(1800);led=0; }
}
}
如果對時間要求精確,則要用到定時器,還要確保電路外接有晶振,並已知晶振頻率