【算法题】刷刷OJ题题题

好多题目都是源自宁大的OJ网站。 宁大OJ
注册个账号,就算不是本校人员也可以刷。
另外还有一些是LeetCode的题目给摘出来了在这里。👉 刷算笔记 [C语言描述]

1286 神奇的斐波那契

这道题卡了我一小时!矩阵的一些操作还是有点不熟悉啊,有待提高!

题目描述

斐波那契数列大家都熟悉吧,不熟悉的问问旁边的吧,
不能多问哦,
现在我们又要用到斐波那契数列了,
给定两个小于等于15的数m,n,
构造一个m行n列的矩阵,规则如下,
第奇数列从上到下是斐波那契数列的前几项
第偶数列从下到上是斐波那契数列的前几项

输入描述

/*
两个数m,n
*/
12 15

输出描述

/*
输出题目描述的矩阵,每个数据占5个字符宽,并左对齐
*/
1    144  1    144  1    144  1    144  1    144  1    144  1    144  1    
1    89   1    89   1    89   1    89   1    89   1    89   1    89   1    
2    55   2    55   2    55   2    55   2    55   2    55   2    55   2    
3    34   3    34   3    34   3    34   3    34   3    34   3    34   3    
5    21   5    21   5    21   5    21   5    21   5    21   5    21   5    
8    13   8    13   8    13   8    13   8    13   8    13   8    13   8    
13   8    13   8    13   8    13   8    13   8    13   8    13   8    13   
21   5    21   5    21   5    21   5    21   5    21   5    21   5    21   
34   3    34   3    34   3    34   3    34   3    34   3    34   3    34   
55   2    55   2    55   2    55   2    55   2    55   2    55   2    55   
89   1    89   1    89   1    89   1    89   1    89   1    89   1    89   
144  1    144  1    144  1    144  1    144  1    144  1    144  1    144
#include <stdio.h>
#include<math.h>

int mins(int x,int y){
    return x<y?x:y;
}

int main()
{
    int i =0,j=0;
    int m =0,n=0;
    int a[15]={0};
    int b[15][15] = {0};
    a[0] = 1;
    a[1] = 1;
    scanf("%d %d",&m,&n);
    //斐波那契数列
    for(i=2;i<m;i++)
        a[i] = a[i-1] + a[i-2];

    
    for(j=0;j<mins(m,n)+abs(m-n);j++)
        for(i=0;i<m;i++){
            b[i][j] = a[i];

    //打印
    for(i=0;i<m;i++){
        for(j=0;j<n;j++){
            if(j%2==0)
                printf("%-5d",b[i][j]);
            else
                printf("%-5d",b[m-1-i][j]);
        }
        printf("%\n");
    }
}

1283 信号强度统计(未完成)

题目描述

在一个偏远的山区,电信部门要去调研那里的信号覆盖情况,
经过扫描得到山区的信号塔分布情况矩形图,矩形图图由0和1组成,
1表示信号塔,0表示非信号塔。
每一个信号塔可以使它周围和自己所在共9个区域的信号强度加1,
他们想快速知道信号强度为0~9的区域各有多少块,0表示没有信号。

输入描述

/*
第一行两个小于等于20的非负整数m、n,表示矩形图的行数和列数。
接下来m行每行n个整数表示第m行n列所在位置是信号塔或非信号塔。
*/
11 10
1 1 0 0 1 0 1 1 0 1
0 0 0 0 0 0 1 1 0 1
0 1 1 1 0 0 1 1 1 1
0 1 0 1 0 0 1 0 0 0
1 1 1 0 1 1 0 1 1 0
1 1 0 0 0 0 1 0 1 0
1 1 1 0 0 0 1 1 0 1
1 0 1 0 0 1 1 1 0 0
0 0 0 0 1 0 1 0 1 0
0 1 1 1 0 0 0 1 1 0
0 1 0 1 0 1 1 1 1 1

输出描述

/*
输出信号强度为0~9的区域各有多少块,共10行。
*/
0
4
17
22
27
21
13
5
1
0

1297 阿拉伯到罗马

题目描述

罗马数字是欧洲在阿拉伯数字(实际上是印度数字)
传入之前使用的一种数码,现在应用较少。
它的产生晚于中国甲骨文的数码,更晚于埃及人的
十进位数字。但是,它的产生标志着一种古代文明的进步。
给出几个罗马数字的基础数字,
I(1),V(5),X(10),
L(50),C(100),D(500),M(1000)
观察下面的数字,了解罗马数字的构成原理 

1    2    3     4    5     6      7       8     9 

I    II   III  IV   V    VI   VII  VIII IX 

10   20    30     40   50   60   70     80      90 

X      XX    XXX  XL    L     LX   LXX  LXXX XC 

给出一个大于0小于1000的阿拉伯数字整数,把它转换成罗马数字并输出。

输入描述

/*
一个阿拉伯数字。
*/
374
782

输出描述

/*
按样例格式输出输入的阿拉伯数字对应的罗马数字。
*/
374=CCCLXXIV
782=DCCLXXXII
#include <stdio.h>

int main()
{
    char *digits[10] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
    char *tens[10] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
    char *hundreds[10] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
    char *thousands[4] = {"", "M", "MM", "MMM"};

    int n, i, j;
    while(scanf("%d",&n)!=EOF){
        printf("%d=", n);
        printf("%s", thousands[n/1000]);
        printf("%s", hundreds[n%1000/100]);
        printf("%s", tens[n%100/10]);
        printf("%s\n", digits[n%10]);
    }
}

1228 三天打鱼两天晒网(1)

题目描述

中国有句俗语叫“三天打鱼两天晒网”。某人从2011年1月1日开始“三天打鱼两天晒网”,问题:输入2011年的任一日期,判断此人在打鱼(fishing)还是在晒网(sleeping)。

输入描述

/*
输入两个正整数a和b,表示2011年的a月b日。如输入9 5表示2011年的9月5日。(假设输入数据都是合法的)*/
9 5

输出描述

/*
如在打鱼,则输出fishing,如在晒网,则输出sleeping。*/
fishing
#include<stdio.h>

int main()
{
    int month = 0;
    int day = 0;
    int sumday=0;
    int flag=0;
    int i;
    int dayofmonth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    scanf("%d %d",&month,&day);
    for(i=1;i<month;i++){
        sumday += dayofmonth[i];
    }
    sumday += day;
    //printf("%d\n",sumday);
    if(sumday%5==1||sumday%5==2||sumday%5==3)
        flag=1;
    else
        flag = 0;
    if(flag)
        printf("fishing\n");
    else
        printf("sleeping\n");
}

1227 数字和为5的整数

题目描述

求三位数[k1,k2]之间所有数字之和为5的整数。

输入描述

/*
输入两个正整数k1和k2,k1和k2都是三位数。K2>K1。
*/
100 200

输出描述

/*
求[k1,k2]之间所有数字之和为5的整数。输出所有符合条件的数,每个数占1行。
*/
104
113
122
131
140
#include<stdio.h>
void handle(int a,int b){
    int i=0,j=0;
    int sum=0;
    int temp=0;
    for(i=a;i<=b;i++){
        temp = i;
        sum = 0;
        for(j=0;j<3;j++)//三位数
        {
            sum+=temp%10;
            temp/=10;
        }
        if(sum==5)
            printf("%d\n",i);
    }
}

int main(){
    int a,b,c;
    scanf("%d %d",&a,&b);
    handle(a,b);
    return 0;
}

1217 超市硬币处理机

题目描述

超市前放置了一个硬币处理机,可以帮你把零钱转换为存款单。在实际应用中,机器中将有相应装置自动识别并计算你的零钱的数目,但是我们现在只能先进行一个模拟的小实验,由你自己输入每种硬币的数目,然后编写程序将其转换成存款单。

输入描述

/*
依次输入1元、5角、1角的零钱的个数。假如输入三个整数3 10 25,则表示有3个1元硬币、10个5角硬币和25个1角的硬币。
*/
3 0 10 

输出描述

/*
输出存单金额,如对上例的输入,输出为
Dollars=10
Change=50
表示存单上的整数金额为10元,零钱金额为50分。
即要求Dollars后显示的是**元的信息,Change后面显示的是**分的信息。
*/
Dollars=4
Change=0
#include<stdio.h>
void handle(int a,int b,int c){
    int dollars;
    int changes;
    double sum;
    int excahnge;
    sum = a*1.0+0.5*b+0.1*c;
    sum *= 100.0;
    dollars = sum/1000*10;
    changes = sum-dollars*100+0.5;//double型-int型是截尾的,要+0.5四舍五入
    printf("Dollars=%d\n",dollars);
    printf("Change=%d\n",changes);
}

int main(){
    int a,b,c;
    scanf("%d %d %d",&a,&b,&c);
    handle(a,b,c);
    return 0;
}

1224 哥德巴赫猜想(2)

题目描述

所谓哥德巴赫猜想,就是指任何一个大于2的偶数,都可以写成两个素数的和。现在输入一个偶数,要求寻找两个素数,使其和等于该偶数。由于可能有多组素数对满足条件,所以本题要求输出两数差最小的那两个素数。

输入描述

/*
输入一个偶整数M,M大于2。
*/
20 

输出描述

/*
对于每个偶数,输出两个彼此最接近的素数,并且其和等于该偶数。(输出时两个素数小的在前,大的在后)。
*/
7 13
#include<stdio.h>
int issushu(int n){
    int i=0;
    int res=1;
    for(i=2;i<n;i++)
        if(n%i==0){
            res = 0;
            break;
        }
    return res;
}

int main(){
    int n=0;
    int i;
    int x;
    int half;
    scanf("%d",&n);
    half = n/2;
    for(i=half;i>0;i--){
        if(issushu(i) && issushu(n-i)){
                printf("%d %d\n",i,n-i);
                break;
        }
    }
    return 0;
}

1214 打印菱形

题目描述

打印出一个由符号“*”组成的菱形图案。

输入描述

/*
输入一个整数n(奇数), 表示菱形的行数。
*/
5

输出描述

/*
菱形用字符 * 表示,每行都没有后缀的空格。
*/
  *
 ***
*****
 ***
  *
#include<stdio.h>

void printlingxing(int n){
	int i=0,j=0;
	int x = n/2+1;
	for(i=1;i<=x;i++){
		for(j=0;j<x-i;j++)
			printf(" ");
		for(j=0;j<2*i-1;j++)
			printf("*");
		printf("\n");
	} 

	for(i=x-1;i>0;i--){
		for(j=x-i;j>0;j--)
			printf(" ");
		for(j=2*i-1;j>0;j--)
			printf("*");
		printf("\n");
	}
}

int main(){
	int n; 
	scanf("%d",&n);
	printlingxing(n);
	return 0;
}   

1213 判断亲密数

题目描述

如果整数A的全部因子(包括1,不包括A本身)之和等于B,并且整数B的全部因子(包括1,不包括B本身)之和等于A,则称整数A和B为亲密数。任意输入两个正整数,判断他们是否为亲密数。若是亲密数,则输出1,否则输出0.

输入描述

/*
输入两个整数。
*/
220 284

输出描述

/*
若是亲密数,则输出1,否则输出0。
*/
1
#include<stdio.h>
#include<math.h>

int isqinmi(int a,int b){
	int i=0;
	int suma=0,sumb=0;
	int flaga=0,flagb=0;
	for(i=1;i<a;i++)
		if(a%i==0)
			suma+=i;
			
	if(suma==b)
		flaga=1;
	
	for(i=1;i<b;i++)
		if(b%i==0)
			sumb+=i;
	
	if(sumb==a)
		flagb=1;
		
	if(flagb && flaga)		
		return 1;
	return 0;
}
int main(){
	int a,b;
	int res;
	scanf("%d %d",&a,&b);
	res =isqinmi(a,b);
	printf("%d\n",res); 
	return 0;
}  

1211 还是鸡兔同笼

题目描述

一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物。

输入描述

/*
第一行是测试数据的组数n,后面跟着n行输入。每组测试数据占一行,每行包含一个正整数a,代表笼子里面脚的总数。
*/
2
3
20

输出描述

/*
输出包含n行,每行对应一个输入,包含2个正整数,第一个是最少的动物数,第二个是最多的动物数。如果没有满足要求的答案,则输出两个0。
*/
0 0
5 10
#include<stdio.h>
#include<math.h>

void jitu(int a){
	int maxs;
	int mins;
	if(a%2==1){
		printf("%d %d\n",0,0);
		return;
	}
	mins = a/4;
	maxs = a/2;
	if(a%4==2){
		mins +=1;
	}
	printf("%d %d\n",mins,maxs);
	
}
int main(){
	int n;
	int a;
	int i=0;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&a);
		jitu(a);
	}
	return 0;
} 

1209 幂之和

题目描述

给定一个n 位整数 (n≥3 ),判断它的每个位上的数字的 n 次幂之和是否等于它本身。
例如:

**3位数153(此时n=3),1^3 + 5^3 + 3^3=153 **

4位数8208(此时n=4),84+24+04+84=8208

输入描述

/*
键盘输入一个整数x
*/
92727

输出描述

/*
若x符合条件则输出“Yes”,否则输出“No”。输出不包含双引号。
*/
Yes
#include<stdio.h>
#include<math.h>
int issum(int n){
	int numcount=0;
	int sum=0;
	int temp = n;
	int temps = n;
	while(n!=0){
		numcount++;
		n/=10;
	}
	
	while(temp!=0){
		sum += pow(temp%10,numcount);
		temp/=10;
	}
	if(sum==temps)
		return 1;
	return 0;
}
int main(){
	int n;
	int x;
	scanf("%d",&n);
	x = issum(n);
	if(x)
		printf("Yes\n");
	else
		printf("No\n");
	return 0;
} 

1172 十进制转换成八进制

题目描述

输入一个十进制整数,把这个数转换为八进制的数输出。

输入描述

/*
输入一个十进制整数。
*/
57

输出描述

/*
输出转化后的八进制数,各数字间空一格,最后一个数据后面也有空格,再换行。
*/
7 1
#include<stdio.h>

void convertnum(int n){
    int x;
    int a[101];
    int i=0;
    int j=0;
    while(n!=0){
        x = n%8;
        a[i++] = x;
        n = n/8;
    }
    for(j=i-1;j>=0;j--)
        printf("%d ",a[j]);
    printf("\n");
}

int main()
{
   int n;
   scanf("%d",&n);
   convertnum(n);
   return 0;
}

1139 单词译码

题目描述

最近网络上又爆出很多关于信息泄露的事情,看来信息时代的保密问题非常关键。怎样才能隐藏你的关键信息呢?作为程序设计的菜鸟一族,你可以先尝试做一些简单的译码工作。对输入的一个任意的单词进行译码输出。译码规律是:用原来字母后面的第4个字母代替原来的字母,并能循环译码。例如,字母A后面第4个字母是E,用E代替A;同理,字母y用c代替。则单词”China”应译为”Glmre”,”Today”应译为”Xshec”。

输入描述

/*
输入一个单词,长度不超过9。假设输入内容全部都是英文字母,不存在其他字符。
*/
Helloz

输出描述

/*
输出译码后的结果。
*/
Lippsd
#include<stdio.h>
#include<string.h>


void convertstr(char s[]){
    int i=0;
    int len = strlen(s);
    char x;
    for(i=0;i<len;i++){
        x = s[i] +4 ;
        if(x >'a'&& x <'z' || x >'A'&& x <'Z')
            printf("%c",x);
        else
            printf("%c",x-26);
    }
    printf("\n");
}

int main()
{
   char str[10]={0};
   scanf("%s",str);
   convertstr(str);
   return 0;
}

1159 字母出现频率

题目描述

从键盘输入一行文本(小于1000字符),统计其中每个英文字母出现的频率,并输出出现过的英文字母及其次数,未出现过的不需要显示。为了简化问题的复杂度,假设在统计过程中不区分字母的大小写,即'A'与'a'被认为是一种字母。

输入描述

/*
先从键盘输入一行文本。以换行符结束。
*/
Studing C Language

输出描述

/*
输出统计结果。
*/
'A':2
'C':1
'D':1
'E':1
'G':3
'I':1
'L':1
'N':2
'S':1
'T':1
'U':2
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void countnumber(char s[]){
    int len = strlen(s);
    int i =0;
    int counts[26];
    for(i=0;i<26;i++){
       counts[i] = 0;
    }
    for(i=0;i<len;i++){
        if(s[i]>='A' && s[i]<='Z'){
           counts[s[i]-'A']++;
        }
        else if(s[i]>='a' && s[i]<='z'){
            counts[s[i]-'a']++;
        }
    }
    for(i=0;i<26;i++){
        if(counts[i]!=0)
            printf("'%c':%d\n",i+'A',counts[i]);
    }
}

int main()
{
   char str[1001]={0};
   gets(str); //可以读取带空格的字符串,回车结束输入
   countnumber(str);
   return 0;
}

1176 统计单词数

题目描述

擎天柱最近很空,他想做一件没有什么意义的事情,就是统计输入文档里单词的总数。

输入描述

/*
输入一行字符表示一篇小文章,每篇小文章都是由英文字母、数字和空格组成,没有标点符号,遇到换行符时表示输入结束。文章最多由1000个字符组成。
*/
You are  my friend 007

输出描述

/*
输出一个整数,代表文章里单词的总数。
*/
5
#include<stdio.h>
#include<string.h>
void countstr(char s[]){
    int i=0;
    int len = strlen(s);
    int sum=0;
    for(i=0;i<len;i++)
		if(s[i]!=' ')
		{
			sum++;
			while(s[i]!=' '&&s[i]!='\0')
			{
				i++;

            }
		}
    printf("%d\n",sum);
}

int main(){
    char str[1000];
    gets(str);
    countstr(str);
    return 0;
}

1175 查找最大元素

题目描述

对于输入的字符串,查找其中的AscII码最大字母,在该字母后面插入字符串"(max)”。不包括引号。

输入描述

/*
输入一行长度不超过100的字符串,字符串仅由大小写字母构成。
*/
abcdefgfedcba

输出描述

/*
输出一行字符串,输出的结果是插入字符串"(max)”后的结果,如果存在多个最大的字母,就在每一个最大字母后面都插入"(max)"。
*/
abcdefg(max)fedcba
#include<stdio.h>
#include<string.h>
void findmax(char s[]){
    int i =0;
    int len = strlen(s);
    char maxc = s[0];
    int a[101]={0};
    for(i=0;i<len;i++)
        if(maxc<s[i])
            maxc = s[i];

    for(i=0;s[i]!='\0';i++){
        if(s[i]!=maxc)
            printf("%c",s[i]);
        else
            printf("%c(max)",s[i]);
    }
    printf("\n");
}

int main(){
    char str[101];
    scanf("%s",str);
    findmax(str);
    return 0;
}

1174 哥德巴赫猜想

题目描述

所谓哥德巴赫猜想是指,任一大于2的偶数都可以写成两个质数之和(严格说来,这是欧拉的等价描述版本)。例如6=3+3,8=3+5,...,18=7+11。迄今为止,这仍然是一个著名的世界难题,被誉为数学王冠上的明珠。试编写程序,验证任一大于2的偶数都能写成两个质数之和。(可能有多种情况,请输出两数差最大的那组)

输入描述

/*
输入一个大于2的偶数N。
*/
16

输出描述

/*
输出两个质数和的形式,小的质数在前,大的质数在后。
*/
16=3+13
#include<stdio.h>
int issushu(int n){
    int i=0;
    int res=1;
    for(i=2;i<n;i++)
        if(n%i==0){
            res = 0;
            break;
        }
    return res;
}

int main(){
    int n=0;
    int i;
    int x;
    scanf("%d",&n);
    for(i=3;i<n;i++){
        if(issushu(i) && issushu(n-i)){
                printf("%d=%d+%d\n",n,i,n-i);
                break;
        }
    }
    return 0;
}

1172 十进制转换成八进制

题目描述

输入一个十进制整数,把这个数转换为八进制的数输出。

输入描述

/*
输入一个十进制整数。
*/
57

输出描述

/*
输出转化后的八进制数,各数字间空一格,最后一个数据后面也有空格,再换行。
*/
7 1

1171 多个数的最小公倍数

题目描述

也许你已经会了求2个数字最小公倍数的方法,但是如果求多个数字的最小公倍数,你又能找到办法吗?

输入描述

/*
首先输入一个整数n表示有n个数,然后输入这n个整数。(n<=100)
*/
5 3 5 7 11 9

输出描述

/*
求出n个整数的最小公倍数。
*/
3465
#include<stdio.h>
int gcd(int a,int b){
     if (b==0)
        return a;
    return gcd(b, a%b);
}

void mutgcd(int a[],int n){
    int i=0;
    int z=0;
    int k = a[0];
    for(i=0;i<n;i++){
        z = gcd(k,a[i]);
        k = k*a[i]/z;
    }
    printf("%d\n",k);
}

int main()
{
    int n;
    int i;
    int a[101];
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    mutgcd(a,n);
}

1181 二维数组的鞍点

题目描述

找出一个2维数组矩阵的鞍点,即该位置上的元素在该行中最大,在该列中最小,可能不存在鞍点,如果存在多个,输出最小的那个!

输入描述

/*
输入 n,m表示二维矩阵的行数和列数,然后根据行列数输入n*m个数据构成一个二维矩阵。。
*/
4 5
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20

输出描述

/*
如果存在鞍点,则输出该鞍点的值,如果不存在则输出not exist。
*/
5
#include<stdio.h>
#include<string.h>
#define N 100
#define M 100
void matirxpoint(int a[N][M],int n,int m){
    int counts=0;
    int i,j;
    int rowmax,columnmin;
    int s=0;
    int k=0;
    int b[M]={0};
    for(i=0;i<n;i++){
        rowmax = a[i][0];
        for(j=0;j<m;j++)
            if(a[i][j]>rowmax)
                rowmax = a[i][j];
        s=0;
        for(j=0;j<m;j++)
            if(a[i][j]==rowmax){
                b[s] = j;
                s++;
            }

        columnmin = rowmax;
        for(j=0;j<s;j++){
            for(k=0;k<n;k++)
                if(columnmin >a[k][b[j]])
                    break;
            if(k==n){
                printf("%d\n",a[i][b[j]]);
                counts++;
            }
        }
    }
    if(counts==0)
        printf("not exist\n");
}

int main(){
    int a[N][M]={0};
    int i,j;
    int n,m;
    scanf("%d %d",&n,&m);
    for(i=0;i<n;i++)
        for(j=0;j<m;j++){
        scanf("%d",&a[i][j]);
    }
    matirxpoint(a,n,m);
}

1180 魔方阵 (未完成)

题目描述

输出魔方阵,所谓魔方阵就是指这样的方阵,它的每一行每一列和对角线之和都相等,例如,三阶魔方阵为

8 1 6 
3 5 7 
4 9 2

要求输出由1—n^2之间的自然数构成的魔方阵。

输入描述

/*
输入该方阵的阶数n(n<=15且n为奇数)。
*/
3

输出描述

/*
输出该n阶魔方阵,两个数字之间用空格间隔
提示:
由于魔方阵的填法有很多种,这里给出一种填法: 
1.将1放在第一行的最中央。 
2.接下来的每个数字都放在前一个数字的右上方。如果右上方被占,则放在前一个数字的下面。
请按照这种方法输出对应的魔方阵! 
*/
8 1 6
3 5 7
4 9 2

1185 城市名排序

题目描述

输入n个城市的名称,进行升序排序并输出。

输入描述

/*
第一行输入一个整数n,表示有n个城市,n不超过100。
接着输入n个字符串,每个字符串代表一个城市名,一个字符串内部不包含空格,字符串长度不超过100。
*/
10
nignbo
hangzhou
quzhou
fuyang
shaoxing
ninghai
lishui
weinan
fujian
guangzhou

输出描述

/*
输出排序后的城市名字。每个城市名占据一行。
*/
fujian
fuyang
guangzhou
hangzhou
lishui
ningbo
ninghai
quzhou
shaoxing
weinan
#include<stdio.h>
#include<string.h>

void sorts(char s1[][101],int n){
    int i =0,j=0;
    char temp[101];
    for(i=0;i<n;i++){
        for(j=i+1;j<n;j++){
            if(strcmp(s1[i],s1[j])>0)
            {
                strcpy(temp,s1[i]);
                strcpy(s1[i],s1[j]);
                strcpy(s1[j],temp);
            }
        }
    }
}

int main()
{
    int n=0,m=0,i=0;
    char a[101][101];
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%s",a[i]);
    sorts(a,n);
    for(i=0;i<n;i++)
        printf("%s\n",a[i]);

    return 0;
}

1188 数字移位

题目描述

有n个整数,要求将前面各数字顺序向后移动m个位置,并将最后面的m个数变成最前面m个数。其中,移动2个位置后的效果如下图所示:

输入描述

/*
第一行输入两个正整数:n,m。n表示原始数据的个数,m表示需要向后移动的位置数。
第二行输入这n个原始整数。(n<=100)
*/
7 3
1 2 5 4 7 8 3

输出描述

/*
输出经过调整后的n个数。
提示:输出时,最后一个数据后面直接换行。
*/
7 8 3 1 2 5 4
#include<stdio.h>
void reverses(int a[],int left,int right){
    int i = 0;
    int temp=0;
    int mid = (right-left+1)/2;
    for(i=0;i<mid;i++){
        temp = a[i+left];
        a[i+left] = a[right-i];
        a[right-i] = temp;
    }
}
//1 2 5 4 7 8 3
//3 8 7 4 5 2 1
//7 8 3 1 2 5 4
int main()
{
    int n=0,m=0,i=0;
    int a[101];
    scanf("%d %d",&n,&m);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    reverses(a,0,n-1);
    reverses(a,0,m-1);
    reverses(a,m,n-1);
    for(i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}

1195 巧妙推算走楼梯

题目描述

有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?

输入描述

/*
输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M(1<=M<=40),表示楼梯的级数。
*/
2 
2
3

输出描述

/*
对于每个测试实例,请输出不同走法的数量。
*/
1
2
#include<stdio.h>

int main()
{
    int n=0,m=0;
    int i =0;
    int dp[41];
    dp[0] = 0;
    dp[1] = 0;
    dp[2] = 1;
    dp[3] = 2;
    for(i=4;i<=40;i++){
        dp[i] = dp[i-1] + dp[i-2];
    }
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&m);
        printf("%d\n",dp[m]);
    }
    return 0;
}

1196 骨牌铺放

题目描述

在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数.例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图

输入描述

/*
输入数据由多行组成,每行包含一个整数n,表示该测试实例的长方形方格的规格是2×n .(1<=n<=50)
*/
1
3
2

输出描述

/*
对于每个测试实例,请输出铺放方案的总数,每个实例的输出占一行。
*/
1
3
2
#include<stdio.h>

//这里做个重复操作,应该把赋值那部分提到main函数里
void divplane(int n){
	__int64 arr[51];
    int i=0;
    arr[1] = 1;
    arr[2] = 2;
    for(i=3;i<=50;i++)
        arr[i] = arr[i-1] + arr[i-2];
    printf("%I64d\n",arr[n]);
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
       divplane(n);
    }
    return 0;
}

1197 平面分割

题目描述

**我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目。比如,一条折线可以将平面分成两部分,两条折线最多可以将平面分成7部分,具体如下所示。 **

输入描述

/*
输入数据的第一行是一个整数C,表示测试实例的个数,然后是C 行数据,每行包含一个整数n,代表折线的数目.
*/
2
1
2

输出描述

/*
对于每个测试实例,请输出平面的最大分割数,每个实例的输出占一行。
提示:保证所有输入输出数据都在int范围内
*/
2
7
#include<stdio.h>

void divplane(int n){
    int res=0;
    res = 2*n*n-n+1; //直接利用数学公式
    printf("%d\n",res);
}

int main()
{
    int n,m;
    int i = 0;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&m);
        divplane(m);
    }
    return 0;
}

1199 判断字符串类型

题目描述

输入一个字符串,其中只能包括数字或字母。对应输入的字符串,输出它的类型。如果是仅由数字构成的那么输出digit,如果是仅由字母构成的那么输出character,如果是由数字和字母一起构成的输出mixed。

输入描述

/*
输入一个字符串,长度不超过1000,且字符串中只包括数字或大、小写字母。
*/
Sun2009

输出描述

/*
输出对应的类型。
*/
mixed
#include<stdio.h>
#include<string.h>

void judgetype(char s[]){
    int i=0;
    int numflag = 0;
    int charflag = 0;
    int len = strlen(s);
    for(i=0;i<len;i++){
        if(s[i]>='0' && s[i]<= '9')
            numflag = 1;
        else if(s[i]>='A' && s[i]<= 'z')
            charflag = 1;
    }
    if(numflag && charflag)
        printf("mixed\n");
    else if(charflag && !numflag)
        printf("character\n");
    else if(numflag && !charflag)
        printf("digit\n");
}

int main()
{
    char s[1000];
    scanf("%s",s);
    judgetype(s);
    return 0;
}

1167 susan的货币兑换

题目描述

Susan到中国观光旅游,她不太熟悉人民币,因此分别将1角,2角,5角,1元,2元,5元,10元,20元,50元,100元的人民币依次排序号(从1开始排序号),她每天将自己手中不同面值人民币的张数输入iPAD,以计算手头的人民币数额。请你帮她编写一个程序,可以根据她手中的不同面值人民币的张数,计算出对应的人民币数额。

输入描述

/*
输入人民币序号及张数。每种面值占据一行。如5 20表示序号为5的人民币有20张。当输入序号或张数为负数时结束。
*/
5 20
8 40
10 10
-1 0

输出描述

/*
输出对应的人民币数值。保留2位小数。
*/
1840.00
#include<stdio.h>
#include<string.h>

//首先,定义一个二维数组,令第一列等于1。
//让每个数等于它上方两数之和。最后,输出二维数组。

double calmoney(int a,int b){
    double arr[10]={0.1,0.2,0.5,1,2,5,10,20,50,100};
    int i=0;
    int j=0;
    double sum=0;
    a = a-1;
    sum = b*arr[a];
    return sum;
}

int main()
{
    int a=0,b=0;
    double sum=0;
    while(scanf("%d %d",&a,&b) && a>=0 && b>=0){
        sum+=calmoney(a,b);
    }
    printf("%.2lf\n",sum);
    return 0;
}

1165 杨辉三角形

题目描述

从键盘输入一个整数n,输出如下所示的n行的杨辉三角形。下图是n为5时的杨辉三角形。

输入描述

/*
输入一个整数n。(1<=n<=15)。
*/
5

输出描述

/*
输出n行的杨辉三角形。
提示:每一个数据的后面都有空格。
杨辉三角构造规则:每行首尾是1,其他每个数字等于上一行上方及左上方的两个数字之和。
*/
1 
1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1 
#include<stdio.h>
#include<string.h>

//首先,定义一个二维数组,令第一列等于1。
//让每个数等于它上方两数之和。最后,输出二维数组。

void yanghui(int n){
    int i=0;
    int j=0;
    int arr[15][15]={0};
    for(i=0;i<n;i++)
        arr[i][0] = 1;
    for(i=0;i<n;i++)
        for(j=i;j>0;j--)
            arr[i][j] = arr[i-1][j-1]+arr[i-1][j];
    for(i=0;i<n;i++){
         for(j=0;j<=i;j++)
            printf("%d ",arr[i][j]);
        printf("\n");
    }
}

int main()
{
    int n=0;
    scanf("%d",&n);
    yanghui(n);
    return 0;
}

1122 百灯判熄

题目描述

有M盏灯,编号为1~M,分别由相应的M个开关控制。开始时全部开关朝上(朝上为开,灯亮),然后进行以下操作:编号凡是1的倍数的灯反方向拨一次开关;是2的倍数的灯再反方向拨一次开关;是3的倍数的灯又反方向拨一次开关,......,直到是M的倍数的灯又反方向拨一次开关。请从键盘输入一个整数m代表灯的数量,求出最后为熄灭状态的灯(不亮)的数量以及编号并输出。

输入描述

/*
输入一个整数m(1≤m≤100)。
*/
100

输出描述

/*
输出为两行,第一行是熄灭状态的灯的数量;第二行是最后为熄灭状态的灯的编号(每个数据以4列的域宽显示)。
*/
10
1   4   9   16   25   36   49   64   81 100
#include<stdio.h>
#include<string.h>

//直接暴力枚举就完事了
void lighton(int n){
    int i=0;
    int j=0;
    int arr[100] = {0};
    int sum=0;
    for(i=1;i<=n;i++)
        for(j=0;j<n;j++)
            if((j+1)%i==0)
                arr[j] = !arr[j];
    for(i=0;i<n;i++)
        if(arr[i]==1)
            sum++;
    printf("%d\n",sum);
    for(i=0;i<n;i++)
        if(arr[i]==1)
            printf("%d ",i+1);
    printf("\n");
}

int main()
{
    int n=0;
    scanf("%d",&n);
    lighton(n);
    return 0;
}

2993 小扬的马(未完成)

题目描述

小扬是一个象棋小能手,其中马是他擅长的棋子,时常被小扬用于下出“七步绝杀马”的精彩场面。现在小扬要考考你对于马行走的理解了,为了使马跳跃的更快乐,棋盘将是一个m行n列的网格,棋盘左下角坐标为(1,1),右上角坐标为(m,n)。现在给出起点坐标与终点坐标,问你马在不出棋盘的情况下能否从起点跳跃到终点(不限跳跃次数)。

输入描述

/*
测试文件包含多个测试用例。第一行一个整数T(1<=T<=1e5)表示测试用例数,接着T组测试用例。
在每个测试仅包含6个正整数:m,n,x0,y0,x1,y1。
*/
2
2 2 1 1 2 2
5 5 1 1 4 4

输出描述

/*
T行,每行输出"YES"或者"NO"(不包含双引号),"YES"代表能够到达,"NO"则表示不能。
*/
NO
YES

2996 小宇和小曾的字符串 (未完成)

题目描述

小宇和小曾有一个共同的爱好是颠倒字符串,他们发现在颠倒字符串的过程中,有一些很奇妙的性质,不过距离总结出来还有一段时间。比较巧的是,正好程序设计院赛马上要开始,那他们便可以偷偷懒将这个总结规律的任务交给你了。你将会得到两行长度相同且只包含小写字母的字符串S和T,请判断它们在任意次Reverse操作之后,两个字符串能够完全相同。
Reverse操作:同时在S串与T串中选择一个长度相同的子串,将这两个子串中的字符顺序反转过来。例如当S="abcde",T="baced",可以在S中选择子串"de",T中选择子串"ba",这样一次操作后S与T便均为"abced"。

输入描述

/*
第一行一个整数T,代表有T组数据(1<=T<=500);
接下来每组数据两行字符串S,T,每组数据中保证S与T字符串长度均小于1e5;
保证所有数据总长度小于4e5。
*/
3
ab
ba
abb
bab
aabc
bcaa

输出描述

/*
T行,每行输出"YES"或者"NO"(不包含双引号),"YES"代表能够变成完全相同,"NO"则表示不能。
*/
NO
YES
YES

1128 分解质因数

题目描述

根据数论的知识可知,任何一个合数都可以写成几个质数相乘的形式,这几个质数都叫做这个合数的质因数。例如:24=2×2×2×3。现在从键盘输入一个正整数,请编程输出它的所有质因数。

输入描述

/*
从键盘输入一个正整数n,n<100000。
*/
180

输出描述

/*
输出该整数的所有质因数。
*/
2 2 3 3 5
#include<stdio.h>
void divide(int n){
    int i=0;
    for(i=2;i<n;i++){
        while(n>i){
            if(n%i==0){
                printf("%d ",i);
                n = n/i;
            }
            else
                break;
        }
    }
    printf("%d\n",n); //还要输出最后一个素数
}

int main()
{
    int n;
    scanf("%d",&n);
    divide(n);
    return 0;
}

1143 汉诺塔

题目描述

汉诺塔问题是这样的:有3根柱子A,B,C,其中A柱上有64个盘子,盘子大小不等,大的在下,小的在上。要求把这64个盘子从A柱移到C柱上,在移动过程中可以借助B柱,每次只允许移动一个盘子,且在移动过程中在三根柱子上都保持大盘在下,小盘在上。从键盘输入一个整数n(n<=64)表示盘子的个数,打印出移动盘子的正确步骤。

输入描述

/*
从键盘输入盘子的个数n。
*/
3

输出描述

/*
打印出n个盘子的移动步骤。每一步骤占据一行。
*/
a->c
a->b
c->b
a->c
b->a
b->c
a->c
#include<stdio.h>
void hanoi(int n,char a,char b ,char c){
    if(n==1)
        printf("%c->%c\n",a,c);
    else{
       hanoi(n-1,a,c,b);
       printf("%c->%c\n",a,c);
       hanoi(n-1,b,a,c);
    }
}
int main()
{
   int n;
   char a='a',b='b',c='c';
   scanf("%d",&n);
   hanoi(n,a,b,c);
}

1146 排列组合

题目描述

计算从m个不同的数中取n个的取法

输入描述

/*
从键盘输入m和n。
*/
5 3

输出描述

/*
输出计算结果。
*/
10
#include<stdio.h>
void comb(int n,int m){
    int res_numerator = 1;
    int res_denominator = 1;
    int j = 0;
    int res=0;
    for(j=m;j>0;j--){
            res_numerator *= n;
            n--;
            res_denominator *= m;
            m--;
    }
    res = res_numerator/res_denominator;
    printf("%d\n",res);
}

int main()
{
   int n,m;
   scanf("%d %d",&n,&m);
   comb(n,m);
   return 0;
}

1148 数字字符出现频率

题目描述

从键盘输入一行文本,统计其中数字字符0~9出现的频率并输出。没有出现的数字字符不要显示。

输入描述

/*
从键盘输入一行文本。以换行符结束。
*/
Hello No 007.

输出描述

/*
输出统计结果。输出内容按照从0到9顺序输出。每个数字的信息占一行,如“0:2”表示数字字符0出现了2次
提示:
	输出内容中:
	0:2 表示数字字符0出现了2次
	7:1 表示数字字符7出现了1次
*/
0:2
7:1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void countnumber(char s[]){
    int number = 0;
    int len = strlen(s);
    int i =0;
    int counts[10];
    for(i=0;i<10;i++){
       counts[i] = 0;
    }
    for(i=0;i<len;i++){
        if(s[i]>='0' && s[i]<='9'){
           counts[s[i]-'0']++;
        }
    }
    for(i=0;i<10;i++){
        if(counts[i]!=0)
            printf("%d:%d\n",i,counts[i]);
    }
}

int main()
{
   char str[200]={0};
   gets(str); // 可以读取带空格的字符串,回车结束输入
   countnumber(str);
   return 0;
}

1150 文章中字符数统计

题目描述

有一篇文章,共有3段文字,每段不超过1000个字符。要求统计其中英文大写字母、英文小写字母、数字的个数。

输入描述

/*
输入3段文字。
*/
Technology firm Apple has become the most valuable company in the US, with its market capitalisation overtaking that of Exxon Mobil.
Apple had briefly become the largest US firm on Tuesday, before dropping back below the oil giant.
But Apple has now managed to stay in the top spot at the close of Wall Street for the first time.

输出描述

/*
输出统计结果,依次显示大写英文字母个数,小写英文字母个数,数字字符个数。
*/
14 252 0
#include<stdio.h>
#include<string.h>

int lownumber(char s[]){
    int counts =0;
    int len = strlen(s);
    int i =0;
    for(i = 0;i<len;i++){
        if(s[i]>='A'&&s[i]<='Z')
            counts++;
    }
    return counts;
}

int highnumber(char s[]){
    int counts =0;
    int len = strlen(s);
    int i =0;
    for(i = 0;i<len;i++){
        if(s[i]>='a'&&s[i]<='z')
            counts++;
    }
    return counts;
}

int numnumber(char s[]){
    int counts =0;
    int len = strlen(s);
    int i =0;
    for(i = 0;i<len;i++){
        if(s[i]>='0'&&s[i]<='9')
            counts++;
    }
    return counts;
}

int lowercasecount(char s[][1000]){
    int counts =0;
    int i =0;
    for(i = 0;i<3;i++){
        counts+= lownumber(s[i]);
    }
    return counts;
}

int highcasecount(char s[][1000]){
    int counts =0;
    int i =0;
    for(i = 0;i<3;i++){
        counts+=highnumber(s[i]);
    }
    return counts;
}

int numcount(char s[][1000]){
    int counts =0;
    int i =0;
    for(i = 0;i<3;i++){
        counts+=numnumber(s[i]);
    }
    return counts;
}

void countstr(char s[][1000]){
    int lowcase = lowercasecount(s);
    int highcase = highcasecount(s);
    int num = numcount(s);
    printf("%d %d %d\n",lowcase,highcase,num);
}

int main()
{
   char str[3][1000]={0};
   int i=0;
   for(i = 0;i<3;i++){
        gets(str[i]);
   }
   countstr(str);
   return 0;
}

1106 是否阶乘之和?

题目描述

输入一个整数N,判断其是否可以表示成一个正整数阶乘的形式或者几个不同正整数的阶乘之和。

输入描述

/*
输入一个整数N。
*/
4
-1
0
6
^Z

输出描述

/*
对应该整数N,若可以表示,输出YES,否则输出NO
提示:单个整数阶乘的最大值到12!,即479001600。	
*/
NO
NO
NO
YES
#include<stdio.h>
#include<string.h>
//判断某数是否为阶乘和
int isFactorialSum(int n) {
    int k = 2;
    if (n <= 0){
        return 0;
    }
    else if (n== 1 || n==2){
        return 1;
    }
    if(n%2 == 1){ //阶乘都是偶数,递归判断
        return isFactorialSum(n-1);
    }
    while(1){
        if (n%k != 0){
          break;
        }
        while(n%k == 0){
              n = n/k;
              k++;
        }
        if(n == 1){
          return 1;
        }
        if(n<k){
          break;
        }
        n--;
    }
    return 0;
}

int main()
{
    int n=0;
    while(scanf("%d",&n)!=EOF){
        if(isFactorialSum(n))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

这题代码是复制网上大佬的,有点看不懂,有没有小伙伴可以交流下思路。

1103 计算等式

题目描述

编程在算式123_45_67_8_9=N的下划线部分填上加号(+)或减号(-),使该等式成立。要求程序运行时输出该等式。(保证数据存在满足的等式)

输入描述

/*
输入一个整数N。
*/
100

输出描述

/*
输出满足条件的等式。若不存在满足的等式,则输出"impossible"(输出不包括引号)
*/
123+45-67+8-9=100
#include<stdio.h>
#include<string.h>

//直接暴力枚举就完事了
void isequeal(int n) {
    int x =0;
    int res = 0;
    char c1, c2, c3, c4;
    for(x=0; x<16; x++ ){
        int v = 123;
        c1 = x & 8 ? '+' : '-';
        if ( x & 8 )  v +=  45; else v -= 45;

        c2 = x & 4 ? '+' : '-';
        if ( x &4 )  v += 67; else v -= 67;

        c3 = x & 2 ? '+' : '-';
        if ( x & 2)  v+= 8; else v -= 8;

        c4 = x & 1 ? '+' :  '-';
        if ( x & 1)  v+= 9; else v -= 9;

        if ( v == n ) {
            printf("123%c45%c67%c8%c9=%d\n",c1,c2,c3,c4,n);
            res = 1;
       }
    }

    if(!res)
        printf("impossible\n");
}

int main()
{
    int n=0;
    scanf("%d",&n);
    isequeal(n);
    return 0;
}

约瑟夫环

题目描述

n个人(0,1,2,3,4...n-1),围成一圈,从编号为k的人开始报数,报数报到m的人出队(报数是1,2,...m这样报的)。下次从出队的人之后开始重新报数,循环往复,当队伍中只剩最后一个人的时候,那个人就是大王。现在,给定n,k,m,请你求出大王的编号。

输入描述

/*
输入一行包含三个整数n,k,m
1<=n<=100,1<=k<=n-1,1<=m<=100
*/
5 1 2

输出描述

/*
输出一个整数
*/
3
#include<stdio.h>
int main()
{
    int n,k,m;
    scanf("%d %d %d",&n,&k,&m);
    int res=0;
    for(int i=1;i<=n;i++){
        res = (res+m)%i;
    }
    printf("%d\n",(res+k)%n);
    return 0;
}

新约瑟夫环(未完成)

题目描述

讲一个比较有意思的故事:约瑟夫是犹太军队的一个将军,在反抗罗马的起义中,他所率领的军队被击溃,只剩下残余的部队40余人,他们都是宁死不屈的人,所以不愿投降做叛徒。一群人表决说要死,所以用一种策略来先后杀死所有人。 于是约瑟夫建议:每次由其他两人一起杀死一个人,而被杀的人的先后顺序是由抽签决定的,约瑟夫有预谋地抽到了最后一签,在杀了除了他和剩余那个人之外的最后一人,他劝服了另外一个没死的人投降了罗马。我们这个规则是这么定的:
在一间房间总共有n个人(编号0~n-1),只能有最后一个人活命。
按照顺时针的顺序时,编号就是从小到大的。
按照如下规则去杀人:
• 所有人围成一圈
• 顺时针(或逆时针)从1开始报数,每次报到q的人将被杀掉(顺时针逆时针交替进行,默认先进行顺时针)
• 被杀掉的人将从房间内被移走
• 然后从新方向上的下一个人开始重新报数,报到q的被杀掉,直到剩余一人
你要做的是:当你在这一群人之间时,你必须选择一个位置以使得你变成那剩余的最后一人,也就是活下来。

输入描述

/*
在第一行中输入2个正整数n、q(0 < n,q ≤ 1000),以空格分隔
*/
5 2

输出描述

/*
在一行输出最后活下来的人编号.
*/
4
//这题和第一题的区别是 该题顺时针逆时针交替进行!

1. 最大公约数

题目描述

输入两个正整数,求其最大公约数。

假如输入

/*
测试数据有多组,每组输入两个正整数
*/
49 14

应当输出

/*
对于每组输入,请输出其最大公约数。 
*/
7
#include<stdio.h>
 int main(){
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF){
        while(b!=0){
            int temp = a%b;
            a = b;
            b = temp;
        }
        printf("%d\n",a);
    }
 }

2. 最小公倍数(未完成)

题目描述

给定两个正整数,计算这两个数的最小公倍数。

假如输入

/*
输入包含多组测试数据,每组只有一行,包括两个不大于 1000 的正整数。
*/
10 14

应当输出

/*
对于每个测试用例,给出这两个数的最小公倍数,每个实例输出一行。 
*/
70

3. 素数判定

题目描述

给定一个数 n,要求判断其是否为素数(0,1,负数都是非素数)。

假如输入

/*
测试数据有多组,每组输入一个数 n。
*/
13 

应当输出

/*
对于每组输入,若是素数则输出 yes,否则输入 no。 
*/
yes
#include<stdio.h>
int issushu(int x){
    if(x==1)
        return 0;
    for(int i=2;i<x;i++){
        if(x%i==0)
            return 0;
    }
    return 1;
}

 int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        if(issushu(n))
            printf("yes\n");
        else
            printf("no\n");
    }
    return 0;
 }

4. 素数(未完成)

题目描述

输入一个整数 n(2<=n<=10000),要求输出所有从 1 到这个整数之间(不包括
1 和这个整数)个位为 1 的素数,如果没有则输出-1。

假如输入

/*
输入有多组数据。 
每组一行,输入 n。
*/
100

应当输出

/*
输出所有从 1 到这个整数之间(不包括 1 和这个整数)个位为 1 的素数(素数之
间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。
*/
11 31 41 61 71

5. 质因数的个数(未完成)

题目描述

求正整数 N(N>1)的质因数的个数。
相同的质因数需要重复计算。如 120=22235,共有 5 个质因数。

假如输入

/*
可能有多组测试数据,每组测试数据的输入是一个正整数 N,(1<N<10^9)。
*/
120

应当输出

/*
对于每组数据,输出 N 的质因数的个数。
提示:1 不是 N 的质因数;若 N 为质数,N 是 N 的质因数。
*/
5

6. 整除问题(未完成)

题目描述

给定 n,a 求最大的 k,使 n!可以被 a^k 整除但不能被 a^(k+1)整除。

假如输入

/*
两个整数 n(2<=n<=1000),a(2<=a<=1000) 
*/
6 10

应当输出

/*
一个整数.  
*/
1

7. 进制转换(未完成)

题目描述

将 M 进制的数 X 转换为 N 进制的数输出。

假如输入

/*
输入的第一行包括两个整数:M 和 N(2<=M,N<=36)。 
下面的一行输入一个数 X,X 是 M 进制的数,现在要求你将 M 进制的数 X
转换成 N 进制的数输出。  
*/
16 10 
F

应当输出

/*
输出 X 的 N 进制表示的数。 
提示:输入时字母部分为大写,输出时为小写。
*/
15

8. 百鸡问题(未完成)

题目描述

用小于等于 n 元去买 100 只鸡,大鸡 5 元/只,小鸡 3 元/只,还有 1/3 元每只
的一种小鸡,分别记为 x 只,y 只,z 只。编程求解 x,y,z 所有可能解。

假如输入

/*
测试数据有多组,输入 n。 
*/
40 

应当输出

/*
对于每组输入,请输出 x,y,z 所有可行解,按照 x,y,z 依次增大的顺序输出。 
*/
x=0,y=0,z=100 
x=0,y=1,z=99 
x=0,y=2,z=98 
x=1,y=0,z=99

9. N 阶楼梯上楼问题(未完成)

题目描述

N 阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式。(要求
采用非递归)

假如输入

/*
输入包括一个整数 N,(1<=N<90)。
*/
4

应当输出

/*
可能有多组测试数据,对于每组数据,输出当楼梯阶数是 N 时的上楼方式
个数。 
*/
5

10. 不容易系列之一(未完成)

题目描述

HDU 有个网名叫做 8006 的男性同学,结交网友无数,最近该
同学玩起了浪漫,同时给 n 个网友每人写了一封信,这都没什么,要命的是,他
竟然把所有的信都装错了信封!注意了,是全部装错哟!现在的问题是:请大家
帮可怜的 8006 同学计算一下,一共有多少种可能的错误方式呢?

假如输入

/*
输入数据包含多个多个测试实例,每个测试实例占用一行,每行包含一个正
整数 n(1<n<=20),n 表示 8006 的网友的人数。
*/
2 
3

应当输出

/*
对于每行输入请输出可能的错误方式的数量,每个实例的输出占用一行。
*/
1 
2

11. 拦截导弹(未完成)

题目描述

某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦
截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发
炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导
弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必
须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。

假如输入

/*
每组输入有两行, 
第一行,输入雷达捕捉到的敌国导弹的数量 k(k<=25), 
第二行,输入 k 个正整数,表示 k 枚导弹的高度,按来袭导弹的袭击时间顺
序给出,以空格分隔。
*/
8 
300 207 155 300 299 170 158 65 

应当输出

/*
每组输出只有一行,包含一个整数,表示最多能拦截多少枚导弹。 
*/
6

12. 寻找完数

题目描述

求1-n内的完数,所谓的完数是这样的数,它的所有因子相加等于它自身,比如6有3个因子1,2,3,1+2+3=6,那么6是完数。即完数是等于其所有因子(除了它自己)相加和的数。

假如输入

/*
测试数据有多组,输入n,n数据范围不大。
*/
6

应当输出

/*
对于每组输入,请输出1-n内所有的完数。如有案例输出有多个数字,用空格隔开,输出最后不要有多余的空格。
*/
6
#include<stdio.h>
int iswanshu(int x){
    int sum=0;
    for(int i=1;i<x;i++){
        if(x%i==0)
            sum+=i;
    }
    return sum==x;
}

 int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++){
            if(iswanshu(i))
                printf("%d ",i);
        }
    }
    return 0;
 }

13. 判断完全平方数因子

题目描述

给定一个数n,判定它是否有一个不为1的完全平方数因子。也就是说,是否存在某个k,k>1,使得k*k能够整除n。

假如输入

/*
每行一个整数n,1<n<10000
*/
15
12
0

应当输出

/*
对于每一个输入的整数,在单独的一行输出结果,如果有不为1的完全平方数因子,则输出Yes,否则输出No。请注意大小写。
*/
No
Yes
#include<stdio.h>

int ishave(int n){
    for(int i=1;i<n;i++){
        if(i*i%n==0)
            return 1;
    }
    return 0;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        if(ishave(n))
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

14. 素数(未完成)

题目描述

输入一个整数 n(2<=n<=10000),要求输出所有从 1 到这个整数之间(不包括
1 和这个整数)个位为 1 的素数,如果没有则输出-1。

假如输入

/*
输入有多组数据。 
每组一行,输入 n。
*/
100

应当输出

/*
输出所有从 1 到这个整数之间(不包括 1 和这个整数)个位为 1 的素数(素数之
间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。
*/
11 31 41 61 71

15. 位数之和

题目描述

对于给定的正整数 n,计算其十进制形式下所有位置数字之和,并计算其平方的各位数字之和。

假如输入

/*
每行输入数据包括一个正整数n(0<n<40000)
*/
4
12
97
39999

应当输出

/*
对于每个输入数据,计算其各位数字之和,以及其平方值的数字之和,输出在一行中,之间用一个空格分隔,但行末不要有空格。
*/
4 7
3 9
16 22
39 36
#include<stdio.h>
#include<algorithm>
using namespace std;

void calsum(int n){
    int sum1=0;
    int sum2=0;
    int temp = n*n;
    while(n!=0){
        sum1+=n%10;
        n = n/10;
    }
    while(temp!=0){
        sum2+=temp%10;
        temp = temp/10;
    }
    printf("%d %d\n",sum1,sum2);
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        calsum(n);
    }
    return 0;
}

1. 计算 A+B

题目描述

求整数 a,b 的和。

假如输入

/*
测试案例有多行,每行为 a,b 的值,a,b 为 int 范围。
输出多行,对应 a+b 的结果。
*/
1 2 
4 5 
6 9

应当输出

/*
 
*/
3 
9 
15

2. 对输入的 n 个数进行排序并输出。

题目描述

求整数 a,b 的和。

假如输入

/*
输入的第一行包括一个整数 n(1<=n<=100)。接下来的一行包括 n 个整数。 
*/
4 
1 4 3 2

应当输出

/*
可能有多组测试数据,对于每组数据,将排序后的 n 个整数输出,每个数后
面都有一个空格。每组测试数据的结果占一行。 
*/
1 2 3 4
#include<stdio.h>
//冒泡排序
 void bublesort(int a[],int n){
     int temp=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n-1-i;j++){
            if(a[j]>a[j+1])
            {
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }

    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }
 }

 int main(){
    int n=0;
    int a[101];
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        bublesort(a,n);
    }
 }


/*-----------------------------------------------------------------------*/
//第二种方法
#include<stdio.h>
#include<algorithm>
using namespace std;

bool cmp(int a,int b){
	return a<b
}
 void arraysort(int a[],int n){
    sort(a,a+n,cmp);
    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }

 }

 int main(){
    int n=0;
    int a[101];
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        arraysort(a,n);
    }
 }


3. 成绩排序

题目描述

有 N 个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名
字符的字母序排序,如果姓名的字母序也相同则按照学生的年龄排序,并输出 N
个学生排序后的信息。

假如输入

/*
测试数据有多组,每组输入第一行有一个整数 N(N<=1000),接下来的 N
行包括 N 个学生的数据。每个学生的数据包括姓名(长度不超过 100 的字符串)、
年龄(整形数)、成绩(小于等于 100 的正数)。
*/
3 
abc 20 99 
bcd 19 97 
bed 20 97

应当输出

/*
将学生信息按成绩进行排序,成绩相同的则按姓名的字母序进行排序。然后
输出学生信息,按照如下格式:姓名 年龄 成绩
提示:学生姓名的字母序区分字母的大小写,如 A 要比 a 的字母序靠前(因为 A 的
ASC 码比 a 的 ASC 码要小)。 
*/
bcd 19 97 
bed 20 97 
abc 20 99
#include<stdio.h>
#include<algorithm>
#include<string.h>

using namespace std; 

struct E{
	char name[101];
	int age;
	int score;
}buf[100];

bool cmp(E a,E b){
	if(a.score!=b.score)
		return a.score<b.score;
	int tmp = strcmp(a.name,b.name);
	if(tmp!=0) return tmp<0;
	else
		return a.age<b.age;	
}

int main()
{
	int n=0;
	while(scanf("%d",&n)!=EOF){
		for(int i=0;i<n;i++){
			scanf("%s%d%d",&buf[i].name,&buf[i].age,&buf[i].score);
		}
		sort(buf,buf+n,cmp);
		for(int i=0;i<n;i++)
			printf("%s %d %d \n",buf[i].name,buf[i].age,buf[i].score);
		
	}
	return 0;
}

4. 日期差值

题目描述

有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们
之间的天数为两天

假如输入

/*
测试数据有多组,每组输入第一行有一个整数 N(N<=1000),接下来的 N
行包括 N 个学生的数据。每个学生的数据包括姓名(长度不超过 100 的字符串)、
年龄(整形数)、成绩(小于等于 100 的正数)。 
*/
20110412 
20110422 

应当输出

/*
有多组数据,每组数据有两行,分别表示两个日期,形式为 YYYYMMDD
*/
11
#include<stdio.h>
#define IsYear(x) x%100!=0&&x%4==0 || x%400==0?1:0

int dayofMonth[13][2]={
	0,0,
	31,31,
	29,28,
	31,31,
	30,30,
	31,31,
	30,30,
	31,31,
	31,31,
	30,30,
	31,31,
	30,30,
	31,31,
};

struct Data{
	int year;
	int month;
	int day;
	void nextDay(){
		day++;
		if(day>dayofMonth[month][IsYear(year)]){
			day=1;
			month++;
		}
		if(month>12){
			month=1;
			year++;
		}
	}
};

int buf[5001][13][32];
int abs(int x)
{
	return x>=0?x:-x; 
}


int main(){
	Data temp;
	temp.year=0;
	temp.month = 1;
	temp.day = 1;
	int count=0;
	while(temp.year<5001){
		buf[temp.year][temp.month][temp.day] =count;
		temp.nextDay();
		count++;
	}
	int y1,y2;
	int d1,d2;
	int m1,m2;
	int dis;
	while(scanf("%4d%2d%2d",&y1,&m1,&d1)!=EOF){
		scanf("%4d%2d%2d",&y2,&m2,&d2);
		dis = abs(buf[y1][m1][d1]-buf[y2][m2][d2])+1;
		printf("%d\n",dis);
	}
	return 0;
}

5. 统计同成绩学生人数

题目描述

读入 N 名学生的成绩,将获得某一给定分数的学生人数输出。

假如输入

/*
测试输入包含若干测试用例,每个测试用例的格式为 
第 1 行:N 
第 2 行:N 名学生的成绩,相邻两数字用一个空格间隔。 
第 3 行:给定分数 
当读到 N=0 时输入结束。其中 N 不超过 1000,成绩分数为(包含)0 到 100
之间的一个整数。 
*/
3 
80 60 90 
60 
2 
85 66 
0 
5 
60 75 90 55 75 
75 
0

应当输出

/*
 对每个测试用例,将获得给定分数的学生人数输出。
*/
1 
0 
2
#include<stdio.h>
int main(){
	int n=0;
	while(scanf("%d",&n)!=EOF&&n!=0)
	{
		int hash[101]={
			0,
		};
		int x;
		for(int i=0;i<n;i++){
			scanf("%d",&x);
			hash[x]++;
		}
		scanf("%d",&x);
		printf("%d",hash[x]);	
	}
	return 0;
}

6. Sort

题目描述

给你 n 个整数,请按从大到小的顺序输出其中前 m 大的数。

假如输入

/*
每组测试数据有两行,第一行有两个数 n,m(0<n,m<1000000),第二行包含 n
个各不相同,且都处于区间[-500000,500000]的整数。 
*/
5 3 
3 -35 92 213 -644

应当输出

/*
 对每组测试数据按从大到小的顺序输出前 m 大的数。
*/
213 92 3

7. 输出梯形

题目描述

输入一个高度 h,输出一个高为 h,上底边为 h 的梯形。

假如输入

/*
一个整数 h(1<=h<=1000)。
*/
4

应当输出

/*
 h 所对应的梯形。
*/
      **** 
    ****** 
  ******** 
********** 

8. 叠筐

题目描述

把一个个大小差一圈的筐叠上去,使得从上往下看时,边筐花色交错。这个
工作现在要让计算机来完成,得看你的了。

假如输入

/*
输入是一个个的三元组,分别是,外筐尺寸 n(n 为满足 0<n<80 的奇整数),
中心花色字符,外筐花色字符,后二者都为 ASCII 可见字符;
*/
11 B A 
5 @ W

应当输出

/*
 输出叠在一起的筐图案,中心花色与外筐花色字符从内层起交错相叠,多筐
相叠时,最外筐的角总是被打磨掉。叠筐与叠筐之间应有一行间隔。
*/
 AAAAAAAAA 
ABBBBBBBBBA 
ABAAAAAAABA 
ABABBBBBABA 
ABABAAABABA 
ABABABABABA 
ABABAAABABA 
ABABBBBBABA 
ABAAAAAAABA
ABBBBBBBBBA 
 AAAAAAAAA 

 

 @@@ 
@WWW@ 
@W@W@ 
@WWW@ 
 @@@ 

9. 找 x(未完成)

题目描述

输入一个数 n,然后输入 n 个数值各不相同,再输入一个值 x,输出这个值在这个数组中的下标(从 0 开始,若不在数组中则输出-1)。

假如输入

/*
测试数据有多组,输入 n(1<=n<=200),接着输入 n 个数,然后输入 x。
*/
2 
1 3 
0

应当输出

/*
 对于每组输入,请输出结果。
*/
-1

10. 查找学生信息

题目描述

输入 N 个学生的信息,然后进行查询。

假如输入

/*
输入的第一行为 N,即学生的个数(N<=1000) 
接下来的 N 行包括 N 个学生的信息,信息格式如下: 
01 李江 男 21 
02 刘唐 男 23 
03 张军 男 19 
04 王娜 女 19 
然后输入一个 M(M<=10000),接下来会有 M 行,代表 M 次查询,每行输入
一个学号,格式如下: 
02 
03 
01 
04
*/
4 
01 李江 男 21 
02 刘唐 男 23 
03 张军 男 19 
04 王娜 女 19 
5 
02 
03 
01 
04 
03

应当输出

/*
 输出 M 行,每行包括一个对应于查询的学生的信息。 
如果没有对应的学生信息,则输出“No Answer!” 
*/
02 刘唐 男 23 
03 张军 男 19 
01 李江 男 21 
04 王娜 女 19 
03 张军 男 19

11. 字符串链接函数MyStrcat

题目描述

不用strcat 函数,自己编写一个字符串链接函数MyStrcat(char dstStr[],charsrcStr[])

假如输入

/*
两个字符串,字符串由小写字母组成。
*/
hello world
good morning

应当输出

/*
链接后的字符串 
*/
helloworld
goodmorning
#include<stdio.h>
#include<string.h>
void MyStrcat(char dstStr[],char srcStr[]){
    int len1,len2;
    len1 = strlen(dstStr);
    len2 = strlen(srcStr);
    for(int i=0;i<len2;i++){
        dstStr[len1++] = srcStr[i];
    }
    dstStr[len1] = '\0';
}

 int main(){
    char s1[101],s2[101];
    while(scanf("%s%s",s1,s2)!=EOF){
        MyStrcat(s1,s2);
        printf("%s\n",s1);
    }
    return 0;
 }

12. 换钱计划

题目描述

一个百万富翁遇到一个陌生人,陌生人找他谈了一个换钱的计划。该计划如下:我每天给你10 万元,你第一天给我1 分钱,第二天2 分钱,
第三天4 分钱……
这样交换 30 天后,百万富翁交出了多少钱?陌生人交出了多少钱?(注意一个是万元,一个是分)

假如输入

/*
该题没有输入
*/

应当输出

/*
输出两个整数,分别代表百万富翁交出的钱和陌生人交出的钱,富翁交出的钱以万元作单位,陌生人交出的钱以分作单位。
*/
300 1073741823
#include<stdio.h>
#include<math.h>

void exchangemoney(){
    int a=0,b=0;
    for(int i=0;i<30;i++){
        a+=10;
        b+=pow(2,i);
    }
    printf("%d %d\n",a,b);

}

 int main(){
    exchangemoney();
    return 0;
 }

13. 逆置字符串

题目描述

输入一个字符串,长度小于等于200,然后将数组逆置输出。

假如输入

/*
测试数据有多组,每组输入一个字符串。
*/
hdssg

应当输出

/*
对于每组输入,请输出逆置后的结果。 
*/
gssdh
#include<stdio.h>
#include<string.h>

void reversestring(char s[]){
    char *p;
    p = s+strlen(s)-1;
    for(int i=0;i<strlen(s);i++)
        printf("%c",*(p--));
    printf("\n");
}

 int main(){
     char str[201];
     while(scanf("%s",str)!=EOF){
        reversestring(str);
     }
    return 0;
 }

14. 大数加和

题目描述

给定a和n,计算a+aa+aaa+a...a(n个a)的和。

假如输入

/*
测试数据有多组,输入a,n(1<=a<=9,1<=n<=100)。
*/
1 10

应当输出

/*
对于每组输入,请输出结果。 
*/
1234567900
/*
这段程序在输入 1 11时出错;错误原因是a超出了int型的最大范围。
要找另外的解决办法。
*/
#include<stdio.h>
#include<string.h>
//1+11+111
int calsum(int a,int n){
    int sum=0;
    int temp = a;
    for(int i=0;i<n;i++){
        sum += a;
        a = a*10+temp;
        //printf("%d",a);
    }
    return sum;
}

 int main(){
     int a=0,n=0;
     int sum=0;
    while(scanf("%d%d",&a,&n)!=EOF){
        sum = calsum(a,n);
        printf("%d\n",sum);
    }
    return 0;
 }

15. 字符串排序

题目描述

输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串。

假如输入

/*
测试数据有多组,输入字符串。
*/
bacd

应当输出

/*
对于每组输入,输出处理后的结果。
*/
abcd
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

void strsort(char s[]){
    int len = strlen(s);
    sort(s,s+len);
    printf("%s\n",s);
}

 int main(){
    char s1[201],s2[201];
    while(scanf("%s",s1)!=EOF){
        strsort(s1);
    }
    return 0;
 }

16. 10个数里的最大值

题目描述

测试数据有多组,每组10个整数。

假如输入

/*
测试数据有多组,每组10个整数。
*/
10 22 23 152 65 79 85 96 32 1

应当输出

/*
对于每组输入,请输出其最大值(有回车)。 
*/
max=152
#include<stdio.h>
void findmax(int a[]){
    int max = a[0];
    for(int i=0;i<10;i++)
    {
        if(a[i]>max)
            max = a[i];
    }
    printf("max=%d\n",max);
}

 int main(){
    int a[10];
    for(int i=0;i<10;i++){
        scanf("%d",&a[i]);
    }
    findmax(a);
    return 0;
 }

17. 去掉s中所有的c字符

题目描述

输入字符串s和字符c,要求去掉s中所有的c字符,并输出结果。。

假如输入

/*
测试数据有多组,每组输入字符串s和字符c。
*/
heallo
a

应当输出

/*
对于每组输入,输出去除c字符后的结果。 
*/
hello
#include<stdio.h>
#include<string.h>

void handlestr(char s[],char x){
    int len = strlen(s);
    int j = 0;
    char p[101];
    for(int i=0;i<len;i++){
        if(s[i]!=x)
            p[j++] = s[i];
    }
    printf("%s\n",p);
}

 int main(){
    char s[101];
    char c;
    while(scanf("%s %c",s,&c)!=EOF){
        handlestr(s,c);
    }
    return 0;
 }

18. 指定矩阵相乘

题目描述

输入为两个矩阵,其中一个为2x3的矩阵,另一个为3x2的矩阵

假如输入

/*
输入为两个矩阵,其中一个为2*3的矩阵,另一个为3*2的矩阵
*/
1 2 3
3 4 5
6 7
8 9
10 11

应当输出

/*
一个2*2的矩阵(每一个数字后都跟一个空格) 
*/
52 58
100 112
#include<stdio.h>
void matrix_muti(int a[][3],int b[][2]){
    int c[2][2]={0};
    for(int i=0; i<2;i++)
        for(int j=0; j<2;j++)
            for(int k=0; k<3;k++)
                c[i][j]+=a[i][k]*b[k][j];

    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++)
            printf("%d ",c[i][j]);
        printf("\n");
    }
}

 int main(){
    int a[2][3],b[3][2];
    for(int i=0;i<2;i++)
        for(int j=0;j<3;j++)
            scanf("%d",&a[i][j]);
    for(int i=0;i<3;i++)
        for(int j=0;j<2;j++)
            scanf("%d",&b[i][j]);
    matrix_muti(a,b);
    return 0;
 }
/*———————————————————————————————————————————————————————————————————————————————————*/
/*
上题为固定大小的矩阵相乘,条件给出了具体的维度,代码的扩展性不够。
以下代码为通用的矩阵相乘代码
*/

19. 计算三角形的边

题目描述

给出三个正整数,计算最小的数加上次小的数与最大的数之差。

假如输入

/*
每一行包括三个数据a, b, c,并且都是正整数,均小于10000。
*/
1 2 3
6 5 4
10 20 15
1 1 100
0 0 0

应当输出

/*
对于输入的每一行,在单独一行内输出结果s。s=min(a,b,c)+mid(a,b,c)-max(a,b,c)。上式中,min为最小值,mid为中间值,max为最大值。 
*/
0
3
5
-98
#include<stdio.h>
#include<algorithm>
using namespace std;

int handdata(int a,int b,int c){
    int x[3] = {a,b,c};
    sort(x,x+3);
    int result = x[0]+x[1]-x[2];
    return result;
}
int main()
{
    int a,b,c;
    int result=0;
    while(scanf("%d %d %d",&a,&b,&c)!=EOF){
        result = handdata(a,b,c);
        printf("%d\n",result);
    }
    return 0;
}

1000 找数字

题目描述

给定一组无序数值,数值的大小在1到百万之间,数值的个数在10-50万个之间。现需要找出其中第5到第10小的整数。

假如输入

/*
一组非0整数,(个数>=10个),0为结束标志。
*/
1
2
3
4
5
6
7
8
9
10
0

应当输出

/*
其中第5到第10小的整数。按序输出,每输出一个整数换行。
*/
5
6
7
8
9
10

解法一:

//使用堆排序
#include<iostream>
using namespace std;
#define maxnum 500000
int a[maxnum];
void AdjustDown(int a[],int k,int len){
	a[0] = a[k];
	for(int i=2*k;i<=len;i*=2){
		if(i<len && a[i]<a[i+1])
			i++;
		if(a[0]>=a[i])
			break;
		else{
			a[k] = a[i];
			k = i;
		}
	}
	a[k] = a[0];
}

void BuildMaxHeap(int a[],int len){
	for(int i = len/2;i>0;i--)
		AdjustDown(a,i,len); 
}

void HeapSort(int a[],int len){
	BuildMaxHeap(a,len);
	int temp = 0;
	for(int i = len;i>0;i--){
		temp = a[1];
		a[1] = a[i];
		a[i] = temp;
		//swap(a[i],a[1]);
		AdjustDown(a,1,i-1);
	}
}


int main()
{
	int n = 1, k;
	while(cin>>k){
		if(k==0)
			break;
		a[n++] = k;
	}
	HeapSort(a,n);
	for(int i=6; i<=11; i++)
		cout << a[i] << endl;
	return 0;
}

解法二:

//使用递归来做

1001 小明的烦恼

题目描述

小明最近新买了一个房间,为了给它做装修,想要给它铺上地砖。然而现有的地砖只有两种规格分别为1米1米、2米2米,由于小明买的房间有点小,宽度只有3米,长度为N米。当然这样一个房间也足够他自己一个人住了。那么如果要给这个房间铺设地砖,且只用以上这两种规格的地砖,请问有几种铺设方案。

假如输入

/*
输入的第一行是一个正整数C,表示有C组测试数据。接下来C行,每行输入一个正整数n(1<=n<=30),表示房间的长度。
*/
2
2
3

应当输出

/*
对于每组输入,请输出铺设地砖的方案数目。
*/
3
5
#include<iostream>
using namespace std;
int a[31];
int main()
{
	int n=0,k=0;
	int i=0;
	a[1]=1;
	a[2]=3;
	for(i=3;i<=30;i++)
	{
		a[i] = 2*a[i-2]+a[i-1];
	}
	cin>>n;
	for(i=n;i>0;i--){
		cin>>k;
		cout<<a[k]<<endl;
	}
	return 0;
}

1002 过河卒/noip2002

题目描述

棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下或向右。同时在棋盘上的任一点有一个对方的马(如图中的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如图中C点上的马可以控制9个点。卒不能走到对方马的控制点。

棋盘用坐标表示,A点坐标(0,0)、B点坐标(n, m) (n,m为不超过20的整数,并由键盘输入),同样马的位置坐标C是需要给出的(C≠A,且C≠B)。现在要求你计算出卒从A点能够到达B点的路径条数。

img

假如输入

/*
B点的坐标(n, m)以及对方马的坐标(x,y),不用判错。
*/
6 6 3 2

应当输出

/*
一个整数(路径的条数)。
*/
17
//使用动态规划来解
#include<iostream>
using namespace std;
#define int long
#define maxsize 21
int dr[8][2] = {{2,1},{1,2},{2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1},{-1,2}};
int dp[maxsize][maxsize];
int mp[maxsize][maxsize];
int n,m,x,y;
int main()
{
	int i,j;
	cin>>n>>m>>x>>y;
	mp[x][y] = 1;
	dp[0][0] = 1;
	for(i=0;i<8;i++){
		mp[x+dr[i][0]][y+dr[i][1]] = 1;
	}
	for(i=0;i<=n;i++)
		for(j=0;j<=m;j++)
		{
			if(!mp[i+1][j]) dp[i+1][j] += dp[i][j];
			if(!mp[i][j+1]) dp[i][j+1] += dp[i][j];
		}
	cout<<dp[n][m]<<endl;
	return 0;
}

第K小的数🤙

题目描述

输入n个数,求其中第k小的数。

输入描述

/*
第一行包含两个整数n和k;n<1000,1<=K<=n
第二行包含n个整数。
*/
15 1
1 3 7 2 4 6 -1 0 9 88 2 5 17 6 1

输出描述

/*
输出第k小的那个整数。
可以通过此题学习分治法
*/
-1
#include <stdio.h>

int getStandard(int arra[], int i, int j) 
{
	int key = arra[i];
	while (i < j)
	{
		while (i < j && arra[j] >= key) j--;
        
		if (i < j) arra[i] = arra[j];
        
		while (i < j && arra[i] <= key) i++;

		if (i < j) arra[j] = arra[i];
	}
	arra[i] = key;
	return i;
}

void QuickSort(int arra[], int low, int high) 
{
	if (low < high) 
	{
		int standard = getStandard(arra, low, high);
		QuickSort(arra, low, standard - 1);
		QuickSort(arra, standard + 1, high);
	}
}

int main() 
{
    int n,k;
    int i=0;
    scanf("%d%d",&n,&k);
    int arra[1000];
    for(i=0;i<n;i++){
        scanf("%d",&arra[i]);
    }
    QuickSort(arra,0,n-1);
    printf("%d",arra[k-1]);
	return 0;
}

棋盘覆盖🌰

题目描述

在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖

输入描述

/*
输入一个整数k,k<=5;
输入特殊格子的坐标x,y。
*/
3
1 2

输出描述

/*
输出一个由数值表示的二维矩阵。填充规则如下:
(1)用数值填充方格;
(2)特殊方格数值为0;
(3)从中心点开始;然后左上、右上、左下、右下的计数顺序填数;同一块用相同数值表示;
(4)每个数值占4个位置空间;右对齐,左补空格。
*/
   3    3    4    4    8    8    9    9
   3    2    0    4    8    7    7    9
   5    2    2    6   10   10    7   11
   5    5    6    6    1   10   11   11
  13   13   14    1    1   18   19   19
  13   12   14   14   18   18   17   19
  15   12   12   16   20   17   17   21
  15   15   16   16   20   20   21   21
//PS:注意输出格式,注意输出格式,注意输出格式!
#include<iostream>
using namespace std;
int board[1025][1025];
static int tile = 1;
 
void Chess_Board(int tr,int tc,int dr,int dc,int size)
{
	if(size==1) return ;
	int t=tile++;
	int s=size/2;
	if(dr<tr+s && dc<tc+s)
		Chess_Board(tr,tc,dr,dc,s);
	else 
	{
		board[tr+s-1][tc+s-1]=t;
	
		Chess_Board(tr,tc,tr+s-1,tc+s-1,s);
	}
	if(dr<tr+s && dc>=tc+s)
		Chess_Board(tr,tc+s,dr,dc,s);
	else 
	{
		board[tr+s-1][tc+s]=t;
	
		Chess_Board(tr,tc+s,tr+s-1,tc+s,s);
	}

	if(dr>=tr+s && dc<tc+s)
		Chess_Board(tr+s,tc,dr,dc,s);
	else
	{
		board[tr+s][tc+s-1]=t;
	
		Chess_Board(tr+s,tc,tr+s,tc+s-1,s);
	}
	if(dr>=tr+s && dc>=tc+s)
		Chess_Board(tr+s,tc+s,dr,dc,s);
	else
	{
		board[tr+s][tc+s]=t;
		Chess_Board(tr+s,tc+s,tr+s,tc+s,s);
	}
}
 
int main()
{
	int i,j;
	int k;
	while(cin>>k)
	{
		int size = 1<<k;
		int x,y;  
		cin>>x>>y;  
		board[x][y]=0;
		Chess_Board(0, 0, x, y, size);
		for(i=0; i<size; i++)
		{
			for(j = 0; j < size; j++)
				printf("%4d",board[i][j]); 
			cout<<"\n";
		}
	}
	return 0;
}

小车问题🚗

题目描述

甲、乙两人同时从A 地出发要尽快同时赶到B 地。出发时A 地有一辆小车,可是这辆小车除了驾驶员外只能带一人。已知甲、乙两人的步行速度一样,且小于车的速度。问:怎样利用小车才能使两人尽快同时到达。

输入描述

/*
仅一行,三个整数, 
分别表示AB 两地的距离s 米(≤2000), 
人的步行速度a 米/秒, 
车的速度b 米/秒,2000>b>a。
*/
120 5 25

输出描述

/*
人同时到达B 地需要的最短时间,单位秒,保留4 位小数(判别同时到达的精度范围)。
*/
9.6000
#include<iostream>
using namespace std;
double S,v1,v2;

int main(){
	scanf("%lf%lf%lf",&S,&v1,&v2);
	double l=0,r=S,mid,t1,t2;
	while(r-l>=0.0001)
	{
		mid=(l+r)/2;
		t1=mid/v2+(S-mid)/v1;
		t2=(2*mid*(v2-v1)+S*(v1+v2))/(v2*(v1+v2));
		if(t1>t2)
			l=mid;
		else 
			r=mid;
	}
	printf("%0.4lf\n",l/v2+(S-l)/v1);
  	return 0;
}

双11的红包雨💰

题目描述

双11到了,据说这2天会下红包雨,每个红包有不同的价值,小k好开心,但有个规则,就只能接掉落在他身旁的10米范围内的红包(0-10这11个位置)。小k想尽可能的多抢红包,这样就可以去买一个华为手机,小k每秒种只能在移动不超过一米的范围内接住红包。小k一开始站在5这个位置,因此在第一秒,他只能移动到4,5,6这三个位置中其中一个位置上接红包。问小k最多可能接到多少价值的红包?

输入描述

/*
第一行输入整数n,表示共有多少个红包,n<1000;
后面n行表示n个红包,每行有三个整数,分别表示红包掉落的位置、时间和价值。
*/
8
3 18 5
7 13 7
1 8 10
2 7 13
10 20 1
3 17 8
10 2 123
3 13 45

输出描述

/*
小k接到的红包价值之和。
*/
81
#include <iostream>
using namespace std;
#define maxsize 1001
int dp[maxsize][maxsize];

//两两比较 
int max_score_two(int x,int y){
	int res;
	res = x>y?x:y;
	return res;
}

//三三比较 
int max_score_three(int x,int y,int z){
	int res;
	res = x>y?x:y;
	res = res>z?res:z;
	res = res>y?res:y;
	return res;
}

int main()
{
	int n,i,j;
	int x_loc,t,v,max_t=0;
	cin>> n;

    for(i=0;i<n;i++){
        cin>>x_loc>>t>>v;
        dp[t][x_loc] = v; //构造dp数组,i表示时间,j表示位置 
        if(max_t<t)
        	max_t = t;
    }
    for(i=max_t;i>=0;i--) 
	{
        for(j=0;j<11;j++)
		{
            if(j==0){
                dp[i][j]=max_score_two(dp[i+1][j],dp[i+1][j+1])+dp[i][j]; //遇到左边界只考虑中间、右边 
            }
            else if(j==10){
                dp[i][j]=max_score_two(dp[i+1][j],dp[i+1][j-1])+dp[i][j]; //遇到右边界只考虑中间、左边 
            }
            else
                dp[i][j]=max_score_three(dp[i+1][j],dp[i+1][j-1],dp[i+1][j+1])+dp[i][j]; //考虑左边、中间、右边 
        }
    }
    cout<<dp[0][5]<<endl;
}

最大连续子段和 🌋

题目描述

给出长度为n的数组,求最大连续子段和, 输出该最大和。

输入描述

/*
第1行输入一个整数n<50;表示输入数组的大小
第2行输入n个数,中间用空格隔开
*/
6
-2 11 -4 13 -5 -2

输出描述

/*
最大连续子段和
*/
20
#include <iostream>
using namespace std;
#define maxsize 51
int dp[maxsize];
//两两比较 
int max_score_two(int x,int y){
	int res;
	res = x>y?x:y;
	return res;
}

int main()
{
    int n,i,max_num=0,sum_=0;
    cin>>n;
    for(i=0;i<n;i++){
        cin>>dp[i];
    }
    max_num = dp[0];
    for(i =1;i<n;i++){
        if(sum_<0)
            sum_=dp[i];
        else
			sum_+=dp[i];
        max_num = max_score_two(max_num,sum_);
    }
    cout<<max_num<<endl;
}

减肥的小K2🍀

题目描述

小K是个苦命的孩子,他的师傅为了多赚钱,以减肥为理由,让他去采药,并说不完成不能吃饭。野地里有许多不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。要求在规定的时间t里,采到的草药的总价值最大。

输入描述

/*
第一行有2个整数T(1≤T≤1000)和M(1≤M≤100),一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。
接下来的M行每行包括两个在1到100之间包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。
*/
70 3
71 100
69 1
1 2

输出描述

/*
1个整数,表示在规定的时间内可以采到的草药的最大总价值。
*/
3
#include<iostream>
using namespace std;
//value_matrix[i][j]表示剩余时间为  j,轮到采摘第 i 种药材时所得到的最大价值
int value_matrix[100][1000];

//存储每种草药的采摘时间和价值
int time[100] = {0};
int value[100] = {0};

int main()
{
	//输入  T,M  分别表示总时间和山洞种可采取的草药数目
	//再根据  M  输入  采集时间和对应价值
	int t,m;
	cin>>t>>m;
	//获取每一株草药耗费时间及对应价值
	for(int i=1; i<=m; i++)
	{
		cin>>time[i]>>value[i];
	}
	for(int i=1; i<=m; i++)
	{
		for(int j=1; j<=t; j++)
		{
		//如果当前剩余时间 j 不够采摘第 i 种草药,那么最大
		//价值等于当前剩余时间 j 下采摘到第 i-1 种草药的最大价值
			if(j<time[i]){
				value_matrix[i][j] = value_matrix[i-1][j];
			}
			else
			{
				/*如果当前剩余时间 j 够采摘第 i 种草药,
				那么最大价值等于  (当前剩余时间 j-第 i 种采摘时间)下
				采摘第 i-1 种草药的最大价值+第 i 种草药的价值  与
				上一种情况下的最大价值  中取大的一个*/
				value_matrix[i][j] = 
                    max(value_matrix[i-1][j],value_matrix[i-1][j-time[i]]+value[i]);
			}
		}
	}
	cout<<value_matrix[m][t]<<endl;
	return 0;
}

最小跳数⌚

题目描述

给定一个非负整数数组,假定你的初始位置为数组第一个位置。数组中的每个元素代表你在那个位置能够跳跃的最大长度。你的目标是到达最后一个下标位置,并且使用最少的跳跃次数。

输入描述

/*
输入一组非负整数数组,数组长度不超过500。
*/
2 3 1 1 4

输出描述

/*
最少经过几次跳跃,可以到达最后一个位置。
*/
2
#include <iostream>
using namespace std;
#define maxsize 501
int a[maxsize];

int jump(int nums[],int n){
	int reach = 0;//当前所能到达的最远坐标
    int last = 0;//上一跳可达最远坐标
    int count = 0;//跳跃次数
    for(int i = 0; i < n; i++) 
	{
        if(i>reach)
		{
            return -1;
    	}
        if (i > last) 
		{
            count++;
            last = reach;
        }
        if (i + nums[i] > reach) 
		{
            reach = i + nums[i];
        }
    }
    return count;
}

int main()
{
	int index = 0,res=0,i=0;
	// ctrl+z 退出输入 
    while(cin>>a[index]){
        index++;
    }
    res = jump(a,index);
    cout<<res<<endl;
}

种树🌲

题目描述

一条街的一边有几座房子。因为环保原因居民想要在路边种些树,路边的地区被分割成块,并被编号成1..N;每个部分为一个单位尺寸大小并最多可种一棵树,每个居民想在门前种些树并指定了三个号码B,E,T,这三个数表示该居民想在B和E之间最少种T棵树。当然,B≤E,居民必须记住在指定区不能种多于区域地块数的树,所以T≤E-B+l。居民们想种树的各自区域可以交叉。你的任务是求出能满足所有要求的最少的树的数量。

输入描述

/*
第一行包含数据N,区域的个数;

第二行包含H,房子的数目;

下面的H行描述居民们的需要:B E T。
*/
9                       
4                       
1 4 2                    
4 6 2
8 9 2
3 5 2

输出描述

/*
输出能满足所有要求的最少的树的数。
*/
5
#include<iostream>
#include<bits/stdc++.h>
using namespace std;

struct tree
{
    int b,e,t;
}a[30001];

int n,h,ans;
bool m[30001];
bool cmp(tree x,tree y)
{
    return x.e<y.e;
}
int main()
{
    cin>>n>>h;
    for(int i=1;i<=h;i++) 
        cin>>a[i].b>>a[i].e>>a[i].t;
    
    sort(a+1,a+h+1,cmp);
    
    for(int i=1;i<=h;i++)
    {
        int cnt_ans=0; //当前区域所种的树的数量
		 
        for(int j=a[i].b;j<=a[i].e;j++)
        {
            if(m[j]) // m[j]表示当前该房子是否已经种好树了 
                cnt_ans++;  
        }
        if(cnt_ans>=a[i].t)
            continue;
        
        for(int j=a[i].e;j>=a[i].b;j--)
        { 
            if(!m[j])  //若当前区域没有种树,则种树
            { 
                m[j]=1;
                cnt_ans++; 
                ans++; //ans表示新种的树的数量 
                if(cnt_ans==a[i].t)
                    break;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

区间问题💡

题目描述

给出n个区间的起点和终点,求最少使用其中多少个区间可以将所有区间所在的区域完全覆盖。(测试的数据确保这1点)。

输入描述

/*
第1行一个整数n,表示n个区间;

第2行开始n行,每行2个整数,表示一个区间范围。

类似[1,4][5,6]被认为是覆盖了[1,6]。
*/
7
1 5 
1 6
3 6
1 7
6 9 
9 10
7 9

输出描述

/*
从起点开始,按区间先后顺序,输出选中的区间。所选的区间应尽可能向终点扩展。
*/
1 7
6 9
9 10
#include<iostream>
#include<algorithm>
using namespace std;
//  定义区间的数据结构
class Interval {
	public:
		int x;
		int y;
};
bool cmp(Interval i1, Interval i2) {
	if(i1.x < i2.x) {
		return true;
	} 
	else if(i1.x == i2.x && i1.y < i2.y) {
		return true;
	} 
	else {
		return false;
	}
}

int main() {
	Interval a[100];
	Interval out[100];
	int n;
	cin >> n;
	for(int i = 0; i < n; i++) {
		cin >> a[i].x >> a[i].y;
	}
	
	int cnt = 0; //  计数输出区间
	sort(a, a+n, cmp); // 升序排序
	int right = a[0].x - 1; // 已覆盖范围的右边界
	int end = a[n-1].y; //  终点位置
	
	for(int i = 0; i < n; )
	{
		// 每次都找到左边界在覆盖范围中且右边界最大的那个区间
		int max_right = a[i].y;
		int max_index = i;
		while(a[i].x <= right + 1 && i < n) 
		{
			if(a[i].y > max_right)
			{
				max_right = a[i].y;
				max_index = i;
			}
			i++;
		}
		right = max_right;
		out[cnt++] = a[max_index];
		i = max_index;
		if(right == end)
			break;
	}
	for(int i = 0; i < cnt; i++)
	{
		cout << out[i].x << " " << out[i].y << endl;
	}
	return 0;
	
}

填格子 ♦️

题目描述

有一个由数字 0、1 组成的方阵中,存在一任意形状的封闭区域,封闭区域由数字1 包围构成,每个节点只能走上下左右 4 个方向。现要求把封闭区域内的所有空间都填写成2。

填写后如下:

输入描述

/*
每组测试数据第一行一个整数 n(1≤n≤30)

接下来 n 行,由 0 和 1 组成的 n×n 的方阵。

封闭区域内至少有一个0 。
*/
6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

输出描述

/*
已经填好数字 2 的完整方阵。
注意矩阵的每个数字后面都有一个空格
*/
0 0 0 0 0 0

0 0 1 1 1 1

0 1 1 2 2 1

1 1 2 2 2 1

1 2 2 2 2 1

1 1 1 1 1 1
#include<iostream>
#include<cstring>
using namespace std;
int a[35][35] = {0}; //  方阵大小

int n;

int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; //  四个方向

int cnt = 0; //  某个封闭域的大小

int cnt_max = 0; //  最大的封闭域大小

int id = 3; //  染色编号

int id_max = id; //  最大的封闭域的染色编号

//  深度搜索某点及所有邻近点,若为 0 则染色
void dfs(int x, int y) {
	//为什么边界是[0, n+1],是因为一开始得先在矩阵的最外层围上一圈 0,
	//以此将不在封闭域内的 0 染色
	if(a[x][y] != 0 || x < 0 || x > n+1 || y < 0 || y > n+1) 
	{
		return;
	}
	a[x][y] = id;
	cnt++;
	for(int i = 0; i < 4; i++) 
	{
		dfs(x + dir[i][0], y + dir[i][1]);
	}
}

int main() {
	cin >> n;
	//  注意数组下标是从 1 开始到 n
	for(int i = 1; i <= n; i++)
    {
		for(int j = 1; j <= n; j++) 
        {
			cin >> a[i][j];
		}
	}
	//  将最外围及邻近的 0 都染色
	dfs(0, 0);
	id++;
	for(int i = 2; i < n; i++)
	{
		for(int j = 2; j < n; j++)
		{
			cnt = 0;
			//  对每个点都要进行深搜
			dfs(i, j);
			if(cnt > cnt_max)
			{
				cnt_max = cnt;
				id_max = id;
			}
			id++;
		}
	}
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			if(a[i][j] == 1) {
				cout << a[i][j] << ' ';
			} 
			else if(a[i][j] != id_max)
			{
				cout << '0' << ' ';
			}
			else
			{
				cout << '2' << ' ';
			}
		}
		cout << endl;
	}
	return 0;
}

N皇后👩

题目描述

N皇后的排列,每行一个不冲突;N<=13。

输入描述

/*
一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。
*/
6

输出描述

/*
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
解的输出顺序为从上到下从左到右,小的优先输出
*/

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

#include<iostream>
using namespace std;
int q[20]={0};       //  初始化每个皇后所在的列数
int solves = 0;     //解法
void queen(int i, int n)
{
	if(i == n+1)
	{     //  所有行全部走完,成功找到一种解法
		solves++;
		if(solves <= 3)
		{       //  只输出前三个解
			for(int j=1; j<=n; j++)
			{
				if(j == n){     //  格式控制,保证输出每行结尾处没有空格
					cout << q[j];
					cout << endl;
				}
				else
					cout << q[j] << " ";
			}
		}
		return ;
	}
	else
		for(int col=1; col<=n; col++)
		{ 
			bool flag = true;
			for(int j=1; j<i; j++)
			{
				if(col==q[j] || i+col==j+q[j] || i-col==j-q[j])
                {
					flag = false;
					break;
				}
			} 
			if(flag)
            {
				q[i] = col;
				queen(i+1, n);
			}
		} 
} 

int main()
{
	int n;
	cin >> n;
	queen(1,n);
	cout<< solves <<endl;
	return 0;
}
posted @ 2021-08-13 22:40  梁君牧  阅读(1397)  评论(0编辑  收藏  举报