编程练习八

来源:互联网 发布:2017人工智能最新消息 编辑:程序博客网 时间:2024/05/29 02:36
  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 65535int 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 35int 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

0 0