时间:2021年3月30日14:00:21
网址:https://www.nowcoder.com/ta/huawei
题目
==================================>1
- 题目描述:计算字符串最后一个单词的长度,单词以空格隔开。
- 输入描述:输入一行,代表要计算的字符串,非空,长度小于5000。
- 输出描述:输出一个整数,表示输入字符串最后一个单词的长度。
C语言
#include
#define MAX_SIZE 5000
int main(void)
{
int cnt, n, n_tmp;
char ch;
char *p = &ch;
cnt = n = n_tmp = 0;
while(1)
{
cnt ++;
if(cnt >= MAX_SIZE)
{
printf("warning:out of range!\n");
return -1;
}
if(n != 0)n_tmp = n;
scanf("%c", p);
if(ch == '\n')break;
else n ++;
if(ch == ' ')n = 0;
}
if(n == 0)n = n_tmp;
printf("%d", n);
return 0;
}
c++
#include
#include
using namespace std;
#define MAX_SIZE 5000
int main(void)
{
string str;
int i;
int n, tmp;
if(str.length() >= MAX_SIZE)
{
cout << "warning:out of range!" << endl;
return -1;
}
getline(cin, str);
n = tmp = 0;
for(i = 0; i < str.length(); i++)
{
if(n != 0)
{
tmp = n;
}
n ++;
if(str[i] == ' ')
{
n = 0;
}
}
if(str[str.length() - 1] == ' ')
{
n = tmp;
}
cout << n << endl;
return 0;
}
==================================>2
- 题目描述
写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字母,然后输出输入字符串中该字母的出现次数。不区分大小写。 - 输入描述:
第一行输入一个由字母和数字以及空格组成的字符串,第二行输入一个字母。 - 输出描述:
输出输入字符串中含有该字符的个数。
#include
#include
#define MAX_SIZE 1024
int main(void)
{
char buf[MAX_SIZE];
char *p = buf;
char ch, ch_tmp;
int cnt;
int i;
int num;
cnt = 0;
while(1)
{
cnt++;
if(cnt >= MAX_SIZE)
{
printf("warning:out of range!\n");
return -1;
}
scanf("%c", p++);
if(*(p - 1) == '\n')break;
}
scanf("%c", &ch);
num = 0;
for(i = 0; i < cnt - 1; i++)
{
ch_tmp = buf[i];
if(ch_tmp >= 'A' && ch_tmp <= 'Z')
{
ch_tmp -= 'A' - 'a';
}
if(ch >= 'A' && ch <= 'Z')
{
ch -= 'A' - 'a';
}
if(ch == ch_tmp)num++;
}
printf("%d", num);
return 0;
}
==================================>3
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作(同一个测试用例里可能会有多组数据(用于不同的调查),希望大家能正确处理)。
注:测试用例保证输入参数的正确性,答题者无需验证。测试用例不止一组。
当没有新的输入时,说明输入结束。
#include
void getNum(int *p, int n)
{
int i;
for(i = 0; i < n; i++)
{
scanf("%d", p++);
}
}
int noRepead(int *p, int n)//返回查重后的数字个数
{
int i, j;
int num;
int pos1, pos2;
num = 1;
for(i = 1; i < n; i++)
{
for(j = 0; j < num; j++)
{
if(*(p + i) == *(p + j))
{
break;
}
if(j == num - 1)
{
*(p + num) = *(p + i);
num++;
break;
}
}
}
return num;
}
void sortNum(int *p, int n)
{
int i, j;
for(i = n - 1; i > 0; i--)
{
for(j = 0; j < i; j++)
{
if(*(p + j) > *(p + j + 1))
{
*(p + j) ^= *(p + j + 1);
*(p + j + 1) ^= *(p + j );
*(p + j) ^= *(p + j + 1);
}
}
}
}
void printArray(int *p, int n)
{
int i;
for(i = 0; i < n ; i++)
{
printf("%d\n", *(p + i));
}
}
int main(void)
{
int num = 7;
int num_array[num];
getNum(num_array, num);
num = noRepead(num_array, num);
sortNum(num_array, num);
printArray(num_array, num);
return 0;
}
他人的思想借鉴:位图占用法。即用连续的1-1000二级制位来代表可能的数字,0代表无,1代表有;
#include
void getNum(int *p, int n)
{
int i;
for(i = 0; i < n; i++)
{
scanf("%d", p++);
}
}
int main(void)
{
int num = 5;
int num_array[num];
int i;
unsigned char data[1001/8 + 1] = {0};
getNum(num_array, num);
for(i = 0; i < num; i++)
{
data[num_array[i] / 8] |= ((unsigned char)1) << (num_array[i] % 8);
}
for(i = 0; i < 1001; i++)
{
if(data[i / 8] & ((unsigned char)1) << (i % 8))
{
printf("%d\n", i );
}
}
return 0;
}
==================================>4
题目描述
•连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组;
•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
输入描述:
连续输入字符串(输入多次,每个字符串长度小于100)
输出描述:
输出到长度为8的新字符串数组
#include
#include
int main(void)
{
int str_num = 2;
char buf[64][8] = {{0},};
int i,j, k;
char str[100] = {0};
int idx;
char *buf_p = buf[0];
int len;
idx = 0;
for(i = 0; i < str_num; i++)
{
gets(str);
len = strlen(str);
j = 0;
while(str[j] != '\0')
{
*(buf_p + idx + j) = str[j];
j++;
}
if(len % 8 != 0)
{
for(j = 0; j < (8 - (len % 8)); j++)
{
*(buf_p + idx + len + j) = '0';
}
idx += len + 8 - (len % 8);
}
else
{
idx += len;
}
}
for(i = 0; i < idx; i++)
{
printf("%c", buf_p[i]);
if((i + 1)% 8 == 0)
{
printf("\n");
}
}
return 0;
}
==================================>5
题目描述
写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。
输入描述:
输入一个十六进制的数值字符串。注意:一个用例会同时有多组输入数据,请参考帖子https://www.nowcoder.com/discuss/276处理多组输入的问题。
输出描述:
输出该数值的十进制字符串。不同组的测试用例用\n隔开
#include
#include
int mapChar(char ch)
{
if(ch >= '0' && ch <= '9')
{
return (ch - '0');
}
else if(ch >= 'a' && ch <= 'f')
{
return (ch - 'a' + 10);
}
else if(ch >= 'A' && ch <= 'F')
{
return (ch - 'A' + 10);
}
else
{
return -1;
}
}
int isHexNum(char *p, int n)
{
int i;
if(p == NULL)
{
printf("isHexNum:input error!\n");
return -2;
}
if(p[0] != '0')
{
return -1;
}
if(p[1] != 'x' && p[1] != 'X')
{
return -1;
}
for(i = 2; i < n; i++)
{
if( !((p[i] >= '0' && p[i] <= '9') ||
(p[i] >= 'a' && p[i] <= 'f') ||
(p[i] >= 'A' && p[i] <= 'F') ||
p[i] == ' '))
{
return -1;
}
}
return 0;
}
int jizhi(char *p, int n)
{
int i;
int ret;
int len;
len = 0;
for(i = 2; i < n; i++)
{
if(p[i] == ' ')break;
len++;
}
ret = 0;
for(i = 0; i < len ; i++)
{
if(mapChar(p[i + 2]) == -1)
{
return -1;
}
ret += mapChar(p[i +2]) << ((len - i - 1) * 4);
}
return ret;
}
int main(void)
{
int num = 2;
int i;
char str[128] = {0};
int ret[num];
for(i = 0; i < num; i++)
{
gets(str);
if(isHexNum(str, strlen(str)) == -1)
{
printf("main:input error:\n");
continue;
}
ret[i] = jizhi(str, strlen(str));
}
for(i = 0; i < num; i++)
{
if(ret[i] == -1)
{
printf("error\n");
}
else
{
printf("%d\n", ret[i]);
}
}
return 0;
}
==================================>6
题目描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
最后一个数后面也要有空格
输入描述:
输入一个long型整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。
#include
long int isPermeNum(long n)
{
int i;
int judge = n;
for(i = 2; judge > 1 && i < judge; i++)
{
if(n % i == 0)
{
return i;//返回最小的质因数(注:1不是质因数)
}
judge = n / i + 1;
}
return 0;
}
int getSubPrimeNum(long int num, long int *p)
{
long ret;
ret = isPermeNum(num);
if(ret >= 2)
{
*p = ret;
getSubPrimeNum(num / ret, p + 1);
}
else
{
*p = num;
return 0;
}
return 0;
}
int main(void)
{
int i;
long int num;
long int member[128] = {0};
int n;
scanf("%d", &num);
getSubPrimeNum(num, member);
for(i = 0; i < 10;i++)
{
if(member[i] < 2 || member[i] >= num)break;
printf("%d ", member[i]);
}
}
==================================>7
题目描述
写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。
输入描述:
输入一个正浮点数值
输出描述:
输出该数值的近似整数值
#include
int toInter(float f)
{
int a = (int)f;
if(f - (float)a >= 0.5)
{
a += 1;
}
return a;
}
int main(void)
{
float f;
scanf("%f", &f);
printf("%d", toInter(f));
return 0;
}
==================================>8
题目描述
数据表记录包含表索引和数值(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。
输入描述:
先输入键值对的个数
然后输入成对的index和value值,以空格隔开
输出描述:
输出合并后的键值对(多行)
#include
#define MAX_NUM 64
typedef struct Record{
int key;
int value;
}Record_t;
typedef struct Table{
int num;
Record_t data[MAX_NUM];
}Table_t;
void showTable(Table_t t)
{
int i;
for(i = 0; i < t.num; i ++)
{
printf("%d ", t.data[i].key);
printf("%d\n", t.data[i].value);
}
}
void tablePro(Table_t *t)
{
//选择排序法
int i, j, k;
Table_t buf;
buf.num = 0;
buf.data[0].key = t->data[0].key;
buf.data[0].value = t->data[0].value;
int cnt;
cnt = 1;
Record_t r_tmp, r_tmp2;
for(i = 1; i < t->num; i++)
{
for(j = 0; j < cnt; j++)
{
if(t->data[i].key < buf.data[j].key)
{
r_tmp = buf.data[j];
buf.data[j] = t->data[i];
for(k = 0; k <= cnt - j ; k++)//插入
{
r_tmp2 = buf.data[j + k + 1];
buf.data[j + k + 1] = r_tmp;
r_tmp = r_tmp2;
}
cnt++;
break;
}
else if(t->data[i].key == buf.data[j].key)
{
buf.data[j].value += t->data[i].value;
break;
}
else if(j == cnt - 1)
{
buf.data[cnt] = t->data[i];
cnt ++;
break;
}
else
{
;
}
}
}
buf.num = cnt;
*t = buf;
}
int main(void)
{
Table_t t;
int record_num = 4;
int i;
scanf("%d", &(t.num));
for(i = 0; i < record_num; i ++)
{
scanf("%d", &(t.data[i].key));
scanf("%d", &(t.data[i].value));
}
tablePro(&t);
showTable(t);
return 0;
}
==================================>9
题目描述
输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
保证输入的整数最后一位不是0。
输入描述:
输入一个int型整数
输出描述:
按照从右向左的阅读顺序,返回一个不含重复数字的新的整数
#include
int mypow(int x, int n)
{
int i;
int ret = 1;
for(i = 0; i < n; i++)
{
ret *= x;
}
return ret;
}
int numPro(int num, int *array_p, int *n_p)
{
if(num % 10 == 0)
{
return -1;
}
int i, j;
int a;
int cnt;
cnt = 1;
*array_p = num % 10;
for(i = 2; mypow(10, i - 1) < num; i++)
{
a = (num % mypow(10, i)) / mypow(10, i - 1);
//printf("a:%d %d i:%d cnt:%d\n", a, mypow(10, i), i, cnt);
for(j = 0; j < cnt; j++)
{
if(*(array_p + j) == a)
{
break;
}
else if(j == cnt - 1)
{
array_p[cnt] = a;
cnt++;
break;
}
}
}
*n_p = cnt;
return 0;
}
int main(void)
{
int i;
int num;
scanf("%d", &num);
int array[16] = {0};
int cnt;
numPro(num, array, &cnt);
for(i = 0; i < cnt; i++)
{
printf("%d", array[i]);
}
return 0;
}
==================================>10
题目描述
编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
例如,对于字符串abaca而言,有a、b、c三种不同的字符,因此输出3。
输入描述:
输入一行没有空格的字符串。
输出描述:
输出范围在(0~127)字符的个数。
#include
int main(void)
{
char buf[1024];
gets(buf);
char str[1024] = {0};
int cnt;
int i, j;
i = 0;
cnt = 1;
str[0] = buf[0];
while(buf[i] != '\0')
{
if(buf[i] == '\n')
{
break;
}
else if(!(buf[i] >= 0 && buf[i] <= 127))
{
continue;
}
for(j = 0; j < cnt; j++)
{
if(buf[i] == str[j])
{
break;
}
else if(j == cnt - 1)
{
str[cnt] = buf[i];
cnt++;
break;
}
}
i++;
}
if(!(buf[0] >= 0 && buf[0] <= 127))cnt--;
printf("%d", cnt);
return 0;
}
==================================>11
题目描述
输入一个整数,将这个整数以字符串的形式逆序输出
程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001
输入描述:
输入一个int整数
输出描述:
将这个整数以字符串的形式逆序输出
#include
#include
int main(void)
{
char buf[32] = {0};
int num;
int len;
int i;
scanf("%d", &num);
sprintf(buf, "%d", num);
i = 0;
len = strlen(buf);
while(buf[i] != '\0')
{
printf("%c", buf[len - i - 1]);
i++;
}
return 0;
}
==================================>12
题目描述
接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)
输入描述:
输入一行,为一个只包含小写字母的字符串。
输出描述:
输出该字符串反转后的字符串。
#include
#include
int main(void)
{
char buf[1024] = {0};
gets(buf);
int len = strlen(buf);
int i;
for(i = 0; i < len; i++)
{
printf("%c", buf[len - i - 1]);
}
return 0;
}
==================================>13
题目描述
将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符
输入描述:
输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。
输出描述:
得到逆序的句子
#include
#include
int main(void)
{
char str[256] = {0};
gets(str);
char buf[64][16] = {{0},};
int idx_a, idx_b;
int i;
int cnt;
i = 0;
idx_a = idx_b = 0;
while(str[i] != '\0')
{
if(str[i] == ' ')
{
if(i > 0 && str[i - 1] != ' ')
{
buf[idx_a][idx_b] = '\0';
idx_a++;
idx_b = 0;
}
i++;
continue;
}
buf[idx_a][idx_b] = str[i];
idx_b++;
i++;
}
if(str[strlen(str) - 1] != ' ')
{
cnt = idx_a + 1;
}
else
{
cnt = idx_a;
}
for(i = 0; i < cnt; i ++)
{
printf("%s ", buf[cnt - i - 1]);
}
return 0;
}
==================================>14
题目描述
给定n个字符串,请对n个字符串按照字典序排列。
输入描述:
输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
输出描述:
数据输出n行,输出结果为按照字典序排列的字符串。
#include
#include
void toLower(char *p, int max)
{
int i;
i = 0;
while(p[i] != '\0')
{
if(p[i] >= 'A' && p[i] <= 'Z')
{
p[i] -= 'A' - 'a';
}
i++;
if(i > max)break;
}
}
int main(void)
{
int num;
scanf("%d", &num);
int i, j;
char buf[512][16] = {{0},};
char str_tmp[16] = {0};
getchar();//接收换行符
for(i = 0; i < num; i++)
{
gets(str_tmp);
toLower(str_tmp, 16 - 1);
strcpy(buf[i],/* strlwrtolower*/(str_tmp));
}
for(i = num - 1; i > 0; i --)
{
for(j = 0; j < i; j ++)
{
if(strcmp(buf[j], buf[j + 1]) > 0)
{
strcpy(str_tmp, buf[j]);
strcpy(buf[j], buf[j + 1]);
strcpy(buf[j + 1], str_tmp);
}
}
}
for(i = 0; i < num; i ++)
{
printf("%s\n", buf[i]);
}
return 0;
}
==================================>15
题目描述
输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。
输入描述:
输入一个整数(int类型)
输出描述:
这个数转换成2进制后,输出1的个数
#include
int main(void)
{
int num;
scanf("%d", &num);
int i;
int tmp;
int cnt ;
cnt = 0;
tmp = 0;
for(i = 0;tmp < num; i++)
{
tmp = (int)((int)1 << i);
if((tmp & num) > 0)cnt++;
}
printf("%d", cnt);
return 0;
}
==================================>16
题目描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法
注意:
1. 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
2. 私有IP地址和A,B,C,D,E类地址是不冲突的
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
示例1
输入
[复制](javascript:void(0);)
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0
输出
[复制](javascript:void(0);)
1 0 1 0 0 2 1
#include
#include
#include
int strCut(char *from, char *to, int start, int end)
{
int len = strlen(from);
int i;
int cnt;
cnt = 0;
for(i = 0; i < len; i ++)
{
if(i >= start && i <= end)
{
to[cnt] = from[i] ;
cnt++;
}
else if(i > end)
{
break;
}
}
to[cnt] = '\0';
return 0;
}
int getCharPos(char *str, char ch, int *pos, int *cnt)
{
int len = strlen(str);
int i;
int cnt_tmp;
cnt_tmp = 0;
for(i = 0; i < len; i ++)
{
if(ch == str[i])
{
pos[cnt_tmp] = i;
cnt_tmp++;
}
}
*cnt = cnt_tmp;
return 0;
}
int isIpaddr(char *str, int *ip)
{
int pos[16] = {0};//有溢出风险
int cnt;
int i;
char ip_array[8][4] = {{0},};
int len = strlen(str);
int ip_tmp;
int tmp;
getCharPos(str, '.', pos, &cnt);
if(cnt != 3)
{
return -1;
}
for(i = 0; i < 2; i++)
{
if(pos[i] >= pos[i+1])
{
return -2;
}
}
for(i = 0; i < 4; i++)
{
if(i == 0)
{
strCut(str, ip_array[i], 0, pos[i] - 1);
}
else if(i == 3)
{
strCut(str, ip_array[i], pos[i - 1] + 1, len - 1);
}
else
{
strCut(str, ip_array[i], pos[i - 1] + 1, pos[i] - 1);
}
}
ip_tmp = 0;
for(i = 0; i < 4; i++)
{
tmp = atoi(ip_array[i]);
if(tmp == 0 && ip_array[i][0] != '0')
{
return -3;
}
if(!(tmp >= 0 && tmp <= 255))
{
return -4;
}
ip_tmp += tmp << ( (3 - i) * 8);
}
*ip = ip_tmp;
return 0;
}
int isMaskOk(char *mask)
{
int value;
if(isIpaddr(mask, &value) != 0)return -1;
int num = sizeof(int);
int i, j;
for(i = 0; i < num * 8 - 1; i ++)
{
if((value & (int)1 << (num * 8 - i - 1)) == 0)
{
for(j = i + 1;j < num * 8; j++)
{
if((value & (int)1 << (num * 8 - j - 1)) != 0)
{
return -1;
}
}
break;
}
}
return 0;
}
int linePro(char *str, char *ip_out, char *mask_out)
{
int pos[16] = {0};
int cnt = 0;
getCharPos(str, '~', pos, &cnt);
if(cnt < 1)
{
return -1;
}
int len = strlen(str);
strCut(str, ip_out, 0, pos[0] - 1);
strCut(str, mask_out, pos[0] + 1, len - 1);
return 0;
}
int ipType(int ip, int *type, int *is_pri)
{
const int start[] =
{
1 << 24,
128 << 24,
192 << 24,
224 << 24,
240 << 24,
//私有地址
10 << 24,
172 << 24 | 16 << 16,
192 << 24 | 168 << 16
};
const int end[] =
{
126 << 24 | 255 << 16 | 255 << 8 |255,
191 << 24 | 255 << 16 | 255 << 8 |255,
223 << 24 | 255 << 16 | 255 << 8 |255,
239 << 24 | 255 << 16 | 255 << 8 |255,
255 << 24 | 255 << 16 | 255 << 8 |255,
//私有地址
10 << 24 | 255 << 16 | 255 << 8 |255,
172 << 24 | 31 << 16 | 255 << 8 | 255 ,
192 << 24 | 168 << 16 | 255 << 8 | 255
};
int i;
*type = 0, *is_pri = 0;
for(i = 0; i < 5; i++)
{
if(ip >= start[i] && ip <= end[i])
{
*type = i + 1;
break;
}
}
for(i = 5; i < 8; i++)
{
if(ip >= start[i] && ip <= end[i])
{
*is_pri = 1;
break;
}
}
return 0;
}
int main(void)
{
int num = 4;
char str[8][128] = {{0},};
int i;
char ip_str[64] = {0};
char mask_str[64] = {0};
int a, b, c, d, e, error, pri;
int ip_value;
int ret;
for(i = 0; i < num; i++)
{
gets(str[i]);
}
a = b = c = d = e = error = pri = 0;
int type, is_pri;
for(i = 0; i < num; i++)
{
memset(ip_str, sizeof(ip_str), 0);
memset(mask_str, sizeof(ip_str), 0);
linePro(str[i], ip_str, mask_str);
if(isMaskOk(mask_str) != 0)
{
error++;
continue;
}
ret = isIpaddr(ip_str, &ip_value);
if(ret == 0)
{
ipType(ip_value, &type, &is_pri);
if(type == 1)a++;
else if(type == 2)b++;
else if(type == 3)c++;
else if(type == 4)d++;
else if(type == 5)e++;
if(is_pri == 1)pri++;
}
else
{
error++;
}
}
printf("%d %d %d %d %d %d %d\n", a, b, c, d, e, error, pri);
return 0;
}
==================================>17
题目描述
计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
注意不允许改变队列元素的先后顺序
请注意处理多组输入输出!
输入描述:
整数N
输出描述:
最少需要几位同学出列
示例1
输入
复制
8
186 186 150 200 160 130 197 200
输出
复制
4
#include
int queueIsOk(unsigned int *array, int n)
{
int i, j;
for(i = 0; i < n - 1; i++)
{
if(!(array[i] < array[i + 1]))
{
for(j = i + 1; j < n - 1; j++)
{
if(!(array[j] > array[j + 1]))
{
return -1;
}
}
}
}
return 0;
}
int queuePro(unsigned int *array, int n)
{
//限制:队列大小不超过32位(一个整形的二进制位数)
if(n > 32)return -1;
int i, j;
int totle;
int cnt;
int out_peple_num;
totle = 1 << n;
unsigned int array_tmp[32];
out_peple_num = n;
for(i = 0; i < totle; i++)
{
cnt = 0;
for(j = 0; j < n; j ++)
{
if(((i & (1 << j)) != 0))
{
array_tmp[cnt] = array[j];
cnt++;
}
}
if(cnt > 0)
{
if(queueIsOk(array_tmp, cnt) == 0 && out_peple_num > (8 - cnt))
{
/*printf("====>0x%8x cnt:%d ", i, cnt);
for(j = 0; j < cnt; j++)
{
printf("%d\t", array_tmp[j]);
}
printf("\n");*/
out_peple_num = 8 - cnt;
}
}
}
return out_peple_num;
}
int main(void)
{
//unsigned int num[] = {186, 186, 150, 200, 160, 130, 197, 200 };
unsigned int num[32];
int n;
int i;
scanf("%d", &n);
if(n > 32)
{
printf("n is bigger than 32\n");
}
for(i = 0; i < n; i++)
{
scanf("%d", &num[i]);
}
printf("%d", queuePro(num, 8));
return 0;
}