編程練習八

  1. 電燈問題
    一條長廊裏依次裝有n(1 ≤ n ≤ 65535)盞電燈,從頭到尾編號1、2、3、…n-1、n。每盞電燈由一個拉線開關控制。開始,電燈全部關着。有n個學生從長廊穿過。第一個學生把號碼凡是1的倍數的電燈的開關拉一下;接着第二個學生把號碼凡是2的倍數的電燈的開關拉一下;接着第三個學生把號碼凡是3的倍數的電燈的開關拉一下;如此繼續下去,最後第n個學生把號碼凡是n的倍數的電燈的開關拉一下。n個學生按此規定走完後,長廊裏電燈有幾盞亮着。
    注:電燈數和學生數一致。

方法一:簡單的雙循環方法,耗時

#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;

#define MAX 65535


int main( )
{
    int i,light_num,countnum,j=1, left_num =0;
    printf("please input the number of the lights:\n");
    scanf("%d",&light_num);
    int a[MAX] = {0};
    while (j <= light_num)
    {
        countnum = 0;
        for (i = 1; i <= light_num; i++ )
        {
            if (j % i == 0) countnum++;
        }
        if (countnum % 2 != 0) left_num++; // 基數的燈還是亮着的
        j++;
    }
    printf("%d",left_num);
    return 0;

}

方法二:本題目可以轉化爲:求不大於N的完全平方數的個數。
對於任何一盞燈,由於它原來不亮,那麼當它的開關被按奇數次時,燈是開着的;當它的開關被按偶數次時,燈是關着的;一盞燈的開關被按的次數,恰等於這盞燈的編號的因數的個數;要求哪些燈還亮着,就是問哪些燈的編號的因數有奇數個.顯然完全平方數有奇數個因數。每個數除以一個數A等於另一個數B,那麼A和B都是它的因數,於是因數是成對出現的,但是要因數是奇數,就必須A=B所以這個數就必須是一個是的平方得到的。

for(int i = 1; i < N; i++)
    {
        if(i*i > N)
            break;
        left_num++;
    }
  1. 相同子串
    輸入一個字符串,判斷是否含有相同的子串(字串長度大於1),是,輸出1,否,輸出0。
    例如12312含有兩個12,所以輸出1;23456則沒有相同子序列,輸出0.

輸入:12312
輸出:1

#include<iostream>
#include<string>

using namespace std;

int main()
{
    string s;
    cout<<"輸入一串數字\n";
    cin>>s;
    bool l = false;
    for(int i = 0; i < s.size()-1; i++)
    {
        for(int j = i+1; j < s.size()-1; j++)
        {
            if(s[i]==s[j] &&s[i+1] == s[j+1])
            {
                l =true;
                break;
            }
        }
    }
    if(l) cout<<"1\n";
    else cout <<"0\n";

    system("pause");
    return 0;
}

3.. 兩個整數相除,將結果用字符串返回。如果是循環小數,將循環的位用括號括起來。
函數原型爲 void div(const int a,const int b,char *str)

輸入:1 3
輸出:0.(3)

#include<iostream>
#include<string>
using namespace std;
const int maxn = 100; //設置字符串的最大位數
const int max_INT = 10000; 
int reminder_exist[max_INT];
int reminder_pos[max_INT];

void div(const int a, const int b, char *str)
{
    int numerator,denominator,quotient, reminder, outcnt = 0;
    int flag = 0; //負數標誌
    int original_numerator = a; //求整數部分用到的分子
    memset(reminder_exist, 0, sizeof(reminder_exist));
    memset(reminder_pos, 0, sizeof(reminder_pos));
    numerator = a; //由於定義const int所以我們要改變分子分母時候,所以我們通過中間變量轉化
    denominator = b;

    if(a*b < 0)
        flag = 1;

    //將分子和分母變成整數
    numerator = numerator < 0 ? -numerator:numerator; 
    denominator = denominator < 0 ? -denominator:denominator;

    quotient = numerator/denominator;
    reminder = numerator%denominator;   
    int integer = quotient;

    //找出循環
    //int found_cycle = 0; 
    int cycle_pos = maxn; //循環的位置
    int cycle_len = 0; //初始化循環長度
    int i = 0;
    for(i = 0; i <= maxn; i++)
    {
        //找出餘數相等的情況,求出循環週期
        if(reminder_exist[reminder])
        {
            cycle_pos = reminder_pos[reminder];
            cycle_len = i - cycle_pos;
            break;
        }
        else
        {
            reminder_exist[reminder] = 1;
            reminder_pos[reminder] = i;
        }

        numerator = reminder *10;
        quotient = numerator/denominator;
        reminder = numerator%denominator; 

        str[outcnt++] = quotient + '0'; //將更新的商存入字符串中
    }
    str[outcnt++] = '\0';

    if(!flag)
    {
        cout << integer << "." ;
    }
    else
        cout << "-" << integer << ".";

    for(int j = 0; j < cycle_pos; j++)
        cout << str[j];

    cout << "(";

    for(int j = cycle_pos; j < i;j++)
        cout <<  str[j];
    cout << ")" << endl;
}


int main()
{
    int a,b,flag = 0;
    char s[maxn];
    cin >> a >> b;
    if(!a && !b)
        return 0;
    div( a, b,s);

    system("pause");
    return 0;
}

4.. 地鐵換乘問題

已知2條地鐵線路,其中A爲環線,B爲東西向線路,線路都是雙向的。經過的站點名分別如下,兩條線交叉的換乘點用T1、T2表示。編寫程序,任意輸入兩個站點名稱,輸出乘坐地鐵最少需要經過的車站數量(含輸入的起點和終點,換乘站點只計算一次)。

地鐵線A(環線)經過車站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18

地鐵線B(直線)經過車站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15

輸入:輸入兩個不同的站名

輸出:輸出最少經過的站數,含輸入的起點和終點,換乘站點只計算一次

輸入樣例:A1 A3

輸出樣例:3

思路:分三種情況討論:1)兩個站點都在A線上,2)兩個站點都在B線上,3)兩個站點在不同的線上,需要換乘。這裏簡單的使用數字代表站點:1~18:A1~A18,19:T1,20:T2,21~35:B1~B15. 且假設如果在不同線上的話,B線站爲終點站。

實驗代碼:

#include <stdio.h>
#include <stdlib.h>

#define LINENUM 35

int main()
{
    //int linestop[LINENUM]; // 1~18 爲A線站點, 19:T1, 20:T2, 21~35 爲B線站點
    int stop1 = 0, stop2 = 0, temp, shortline = 0;


    printf("please input the two stop in number: here 1~18 for A1 ~ A18, 19:T1, 20:T2, 21~35 for B1 ~ b15, and stop1 < stop2.\n");
    scanf("%d%d", &stop1, &stop2);

    //如果站點都在A線
    if ( stop1 >= 1 && stop1 <= 20  && stop2 >=1 && stop2 <=20)
    {
        temp = ( stop2 - stop1 + 1) < (20 - (stop2 - stop1) + 1) ? (abs(stop1 - stop2) + 1) :( 20 - abs(stop1 - stop2) + 1);
        shortline = temp;
    }

    // 如果站點都在B線
   if (stop1 >= 19 && stop1 <= 35 && stop2 >= 19 && stop2 <= 35)
    {
        if (stop1 == 19)
        {
            if( stop2 >= 26 && stop2 <= 30)
                shortline = stop2 - stop1 - 5;
            else if (stop2 >30 )
                shortline = stop2 - stop1 -5 ;
            else
                shortline =  stop2 - stop1 + 1;
        }

        if (stop1 == 20)
        {
            if( stop2 >= 26 && stop2 <= 30)
                shortline = stop2 - stop1 + 1;
            else if (stop2 >30 )
                shortline = stop2 - stop1 + 2;
            else if (stop2 = 19)
                shortline =  1 + 4 + 1;
            else
                shortline = stop2 - 19 + 6;
        }
         if (stop1 <= 25)
        {
            if( stop2 >= 26 && stop2 <= 30)
                shortline = stop2 - stop1 + 1 + 1;
            else if (stop2 >30 )
                shortline = stop2 - stop1 + 2;
            else if (stop2 = 20)
                shortline = 5 + 1 + 4 + 1;
            else
                shortline = stop2 - stop1 + 1;
        }
        if (stop1 < 31)
        {
            if( stop2 >= 26 && stop2 <= 30)
                shortline = stop2 - stop1 + 1 ;
            else if (stop2 >30 )
                shortline = stop2 - stop1 + 2;
            else
                shortline = 5 + 1 ;
        }
        if (stop1 >= 31)
        {
            shortline = stop2 - stop1 + 1;
        }
    }

    //如果站點在A、B線上
    if ( stop1 < 10 )
    {
        if ( stop2 > 20 && stop2 < 26)
            shortline = 9 - stop1 + 1 + 26-stop2;
        if ( stop2 >= 26 && stop2 <= 30)
            shortline = (9 - stop1 + 1 + 1 + stop2 - 26 + 1) < (stop1 - 1 + 1 + 6 + 31 - stop2) ? (9 - stop1 + 1 + 1 + stop2 - 26 + 1) : (stop1 - 1 + 1 + 6 + 31 - stop2);
        if (stop2 >= 31)
            shortline = (9 - stop1 + 1 + 7 + stop2 - 31 + 1) < (stop1 - 1 + 1 + 6 + stop2 - 31 + 1)? (9 - stop1 + 1 + 7 + stop2 - 31 + 1) : (stop1 - 1 + 1 + 6 + stop2 - 31 + 1);

    }
    if (stop1 >= 10 && stop1 <= 13)
    {
        if ( stop2 > 20 && stop2 < 26)
            shortline = stop1 - 10 + 1 + 26 - stop2;
        if ( stop2 >= 26 && stop2 <= 30)
            shortline = (stop1 -10 + 1 + stop2 - 26 + 1) < (13 - stop1 + 1 + 31 - stop2) ? (stop1 -10 + 1 + stop2 - 26 + 1): (13 - stop1 + 1 + 31 - stop2);
        if (stop2 >= 31)
            shortline =  13 - stop1 + 1 + 1+ stop2 - 31 + 1;
    }
    if (stop1 > 13 && stop1 <= 18)
    {
        if ( stop2 > 20 && stop2 < 26)
            shortline = ( stop1 - 14 + 1 + 10 + 26 - stop2) < ( 19 - stop1 + 1 + 7 + 26 - stop2) ? ( stop1 - 14 +1 + 10 + 26 - stop2) : ( 19 - stop1 + 1 + 7 + 26 - stop2);
        if ( stop2 >= 26 && stop2 <= 30)
            shortline = (stop1 -14 + 1 + 10 + stop2 - 26 + 1) < (19 - stop1 + 1 + 1 + 31 - stop2) ? (stop1 -14 + 1 + 10 + stop2 - 26 + 1): (19 - stop1 + 1 + 1 + 31 - stop2);
        if (stop2 >= 31)
            shortline =  19 - stop1 + 1  + 1 + stop2 - 31 + 1;
    }
    printf("%d\n", shortline);

    system("pause");

    return 0 ;
}

這裏寫圖片描述

後來百度了一下,這到題還有這樣的一個思路:http://www.2cto.com/kf/201309/247411.html

另外還有類似的:http://www.bkjia.com/ASPjc/744512.html

這裏剛開始調試程序的時候出現了scanf問題:
如果是scanf(“%d,%d,%d”,&a,&b,&c);用非格式符“ , ”作間隔符,故輸入時應爲:5,6,7

如果是scanf(“%d %d %d”,&a,&b,&c);,其中沒有“,”分隔符,則輸入不需要用逗號隔開,使用空格就行:5 6 7

參閱:http://blog.csdn.net/to_xidianhph_youth/article/details/37592527

發佈了46 篇原創文章 · 獲贊 25 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章