1.设有 n 个正整数,将他们连接成一排,组成一个最大的多位整数。
如: n =3时,3个整数13,312,343,连成的最大整数为34331213。
如: n =4时,4个整数7,13,4,246连接成的最大整数为7424613。
#include <iostream>
#include <string>
using namespace std;
#define M 100
bool Compare(string a, string b)
{
if(a + b >= b + a)
return false;
else
return true;
}
int main() {
string String_Num[] = {"7", "13", "4", "246"};
int n = 4;
for(int i = 0; i < n; i++)
cout << String_Num[i]<<" ";
cout << endl;
for(int i = 0; i < n - 1; i++)
{
for(int j = n - 1; j > i; j--)
{
if(Compare(String_Num[j - 1], String_Num[j]))
{
string temp = String_Num[j];
String_Num[j] = String_Num[j - 1];
String_Num[j - 1] = temp;
}
}
}
for(int i = 0; i < n; i++)
cout << String_Num[i] << " ";
cout << endl;
return 0;
}
2.继MIUI8推出手机分身功能之后,MIUI9计划推出一个电话号码分身的功能:首先将电话号码中的每个数字加上8取个位,然后使用对应的大写字母代替(" ZERO “,” ONE ", TWO “,” THREE ", FOUR ", FIVE “,” SIX “)” SEVEN ", EIGHT “,” NINE "),然后随机打乱这些字母,
所生成的字符串即为电话号码对应的分身。要求输入电话号码的分身,输出分身前的电话号码,按从小到大的顺序输出。
例:输入
EIGHT
ZEROTWO0NE
OHWETENRTEO
OHEWTIEGTHENRTEO
输出
0
234
345
0345
3.给定一个十进制的正整数 number ,选择从里面去掉一部分数字,希望保留下来的数字组成的正整数最大。
#include <iostream>
using namespace std;
#define M 100
int a[M];
int b[M];
int main() {
int num;
int deletenum;
int i = 0;
int temp;
cin >> num;
cin >> deletenum;
while(num)
{
a[i] = num % 10;
num = num / 10;
i++;
}
//int n = sizeof(a) / sizeof(a[0]);
int n = i;
for(int m = 0; m < n; m++)
b[m] = a[m];
//cout<<a[m];
for(int r = 0; r < n - 1; r++)
{
for(int j = 0; j < n - r -1; j++)
{
if(a[j] > a[j + 1])
{
int tempa = a[j];
a[j] = a[j + 1];
a[j + 1] = tempa;
}
}
}
int sum = 0;
for(int k = n-1;k >= 0; k--)
{
//cout << a[k];
for(int i = 0; i < deletenum; i++)
{
if(b[k] == a[i])
{
b[k] = -1;
}
}
}
for(int k = n - 1; k >= 0; k--)
{
if(k >= 0 && b[k] != -1)
sum = sum * 10 + b[k];
}
std::cout << sum << std::endl;
return 0;
}
4.酒店房间的价格录入是通过时间段来录入的,比如10月1日至10月7日800元,10月8日至10月20日500元,请实现以下函数,输入是某个酒店多个日期段的价格,每个日期段(终止日期大于等于起始日期)和对应的价格使用长度为3的数组来表示,比如[1,20,300],[10,40,250]分别表示从某天开始第1天到第20天价格都是300,第10天到第40天价格都是250,这些日期端有可能重复,重复的日期的价格以后面的为准,请以以下规则合并并输出合并结果:
1.相邻两天的价格如果相同,那么这两个日期段应该合并
2.合并的结果应该以起始日期从小到大排序
例:输入价格区间的个数 n 以及每个区间
1 1 100
2 3 100
4 5 110
输出
[1, 3, 100]
[4, 5, 110]
#include <iostream>
using namespace std;
#define M 1000
int main() {
int start, end, price;
int Hotel_Price[M] = {0};
while(cin >> start)
{
cin >> end >> price;
{
if(start == 0)
{
std::cout << "输入错误" << std::endl;
break;
}
for(int i = start; i <= end; i++)
Hotel_Price[i] = price;
}
}
for(int i = 1; i <= end; i++)
cout<< Hotel_Price[i] << " ";
cout << endl;
int lflag = 0;
int tempPrice = 0;
for(int i = 1; i <= end; i++)
{
if(lflag == 0)
{
cout << "[" << i;
lflag = 1;
tempPrice = Hotel_Price[i];
continue;
}
if(tempPrice != Hotel_Price[i])
{
cout << "," << --i << "," << Hotel_Price[i] << "]";
cout <<endl;
lflag = 0;
}
if(i == end)
cout << "," << end << "," << tempPrice << "]";
}
return 0;
}
5.小明同学学习了不同的进制之后,拿起了一些数字做起了游戏。小明同学知道,在日常生活中我们最常用的是十进制数,而在计算机中,二进制数也很常用。现在对于一个数字 X ,小明同学定义出了两个函数 f ( x )和 g ( x )。
f ( x )表示把 x 这个数用十进制写出后各个数位上的数字之和。如 f (123)=1+2+3=6。g(x)表示把 x 这个数用二进制写出后各个数位上的数字之和。如123的二进制表示为1111011那么, g (123)=1+1+1+1+0+1+1=6。小明同学发现对于一些正整数×满足 f ( x )= g ( x ),他把这种数称为幸运数,现在他想知道,大于 o 且小于等于 n 的幸运数有多少个?要求输入 n ,输出幸运数的个数以及每个幸运数的二进制表示例:输入21输出3
#include <iostream>
using namespace std;
int Decimal(int num)
{
int sum = 0;
while(num)
{
sum += num % 10;
num = num / 10;
}
return sum;
}
int Binary(int num)
{
int sum = 0;
while(num)
{
sum += num % 2;
num = num / 10;
}
return sum;
}
int main() {
int n;
cin >> n;
int count = 0;
for(int i = 1; i <= n; i++)
{
if(Decimal(i) == Binary(i))
{
count++;
}
}
cout << count;
return 0;
}
6.战争游戏的至关重要环节就要到来了,这次的结果将决定王国的生死存亡,小 B 负责首都的防卫工作。首都位于一个四面环山的盆地中,周围的 n 个小山构成一个环,作为预警措施,小 B 计划在每个小山上设置一个观察哨,日夜不停的瞭望周围发生的情况。一旦发生外地入侵事件,山顶上的岗哨将点燃烽烟,若两个岗哨所在的山峰之间没有更高的山峰遮挡且两者之间有相连通路,则岗哨可以观察到另一个山峰上的烽烟是否点燃。由于小山处于环上,任意两个小山之间存在两个不同的连接通路。满足上述不遮挡的条件下,一座山峰上岗哨点燃的烽烟至少可以通过一条通路被另一端观察到。对于任意相邻的岗哨,一端的岗哨一定可以发现一端点燃的烽烟。小 B 设计的这种保卫方案的一个重要特性是能够观测到对方烽烟的岗哨对的数量,她希望你能够帮她解决这个问题。要求输入小山的数量和各个山的高度,输出能互相观察到的岗哨的对数.
#include <iostream>
using namespace std;
#define MaxSize 100
int main() {
int n;
cin >> n;
int high[MaxSize];
int sum = n;
int map[MaxSize][MaxSize] = {0};
for(int i = 0; i < n; i++)
cin >> high[i];
for(int i = 0; i < n; i++)
{
for(int j = (i + 2) % n; j != i - 1; j += (i + 1) % n)
{
if(high[j - 1] < high[i] && high[j - 1] < high[j] && map[i][j] != 1)
{
sum++;
map[i][j] = 1;
map[j][i] = 1;
}
else
break;
}
}
std::cout << sum << std::endl;
return 0;
}
7.将一句话的单词进行倒置,标点不倒置。比如I like beijing.经过函数后变为: beijing. like I
#include <iostream>
#include <string.h>
using namespace std;
int main() {
char phaseNum[] = {"I like Beijing."}, temp;
int n = strlen(phaseNum) - 1;
int i = 0;
int j = n;
while(i != j)
{
temp = phaseNum[i];
phaseNum[i] = phaseNum[j];
phaseNum[j] = temp;
i++;
j--;
}
i = 0;
int start = 0, end = 0;
while(phaseNum[i])
{
if(phaseNum[i] != ' ')
{
start = i;
while(phaseNum[i] != '\0' && phaseNum[i] != ' ') i++;
end = i - 1;
}
while(start < end)
{
temp = phaseNum[start];
phaseNum[start] = phaseNum[end];
phaseNum[end] = temp;
start++;
end--;
}
i++;
}
for(i = 0; i <= n; i++)
cout << phaseNum[i];
return 0;
}
8.洗牌在生活中十分常见,现在需要写一个程序模拟洗牌的过程。现在需要洗2n张牌,从上到下依次是第1张,第2张,第3张一直到第2n张。首先,我们把这2n张牌分成两堆,左手拿着第1张到第 n 张(上半堆),右手拿着第 n +1张到第/2n张(下半堆)。接着就开始洗牌的过程,先放下右手的最后一张牌,再放下左手的最后一张牌,接着放下右手的倒数第二张牌,再放下左手的倒数第二张牌,直到最后放不左手的第一张牌。接着把牌合并起来就可以了。
例如有6张牌,最开始牌的序列是1,2,3,4,5,6。首先分成两组,左手拿着1,2,3;右手拿着4,5,6。在洗牌过程中按顺序放下了6,3,5,24,1。把这六张牌再次合成一组牌之后,我们按照从上往下的顺序看这组牌,就变成了序列1,4,2,5,3,6。现在给出一个原始牌组,请输出这副牌洗牌 k 次之后从上往下的序列。
#include <iostream>
using namespace std;
#define M 6
void ChangeCard(int a[], int b[], int i, int j)
{
for(int x = 0; x < M; x++)
{
if(x % 2 == 0 && j >= M / 2)
b[x] = a[j--];
if(x % 2 == 1 && i >= 0)
b[x] = a[i--];
}
}
void InputChage(int a[], int b[])
{
int temp;
for(int i = 0; i < M / 2; i++)
{
temp = b[i];
b[i] = b[M - i - 1];
b[M - i - 1] = temp;
}
for(int j = 0; j < M; j++)
a[j] = b[j];
}
int main()
{
int a[M] = {1, 2, 3, 4, 5, 6};
int b[M];
int k;
cin >> k;
int n = 1;
int i = M / 2 - 1, j = M - 1;
while(n <= k)
{
ChangeCard(a, b, i, j);
InputChage(a, b);
i = M / 2 - 1;
j = M - 1;
n++;
}
for(int m = 0; m < M; m++)
cout << b[m];
return 0;
}
9.n只奶牛坐在一排,每个奶牛拥有 i 个苹果,现在你要在它们之间转移苹果,使得最后所有奶牛拥有的苹果数都相同,每一次,你只能从一只奶牛身上拿走恰好两个苹果到另一个奶牛上,问最少需要移动多少次可以平分苹果。要求输入奶牛的数量和每只奶牛的苹果数,输出移动次数,如果方案不存在输出-1。
例:
输入
4
7 15 9 5
输出
3
#include <iostream>
using namespace std;
#define M 100
int main() {
int num;
cin >> num;
int sum = 0;
int a[M];
int ave;
int count;
for(int i = 0; i < num; i++)
{
cin >> a[i];
sum += a[i];
}
if(sum % num != 0)
cout << -1;
else
{
ave = sum / num;
for(int i = 0; i < num; i++)
{
if(((a[i] - ave) % 2) != 0)
{
cout << -1;
break;
}
else
{
if(a[i] - ave > 0)
count += a[i] - ave;
}
}
cout << "需要移动的次数为:" << count / 2 << endl;
}
return 0;
}
10.扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3A,2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写 joker 表示小王,大写 JOKER 表示大王):
345678910JQKA2jokerJOKER
输入两手牌,两手牌之间用“一”连接,每手牌的每张牌以空格分隔,“”两边没有空格,
如:444 4-joker JOKER
请比较两手牌大小,输出较大的牌组,如果不存在比较关系则输出 ERROR
基本规则:
(1)输入每手牌可能是个子,对子,顺子(连续5张),三个,炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子)
(3)大小规则跟大家平时了解的常见规则相同,个子,对子,三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;
(4)输入的两手牌不会出现相等的情况。
提示:
(1)除了炸弹和对王之外,其他必须同类型比较。
(2)输入已经保证合法性,不用检查输入是否是合法的牌。
(3)输入的顺子已经经过从小到大排序,因此不用再排序了,
输入4 4 4 4-joker JOKER
输出 joker JOKER
#include <iostream>
#include <string>
using namespace std;
int count(string s)
{
int n = 0;
int pos = 0;
while((s.find(" ")) != string::npos)
{
pos = s.find(" ");
if(pos + 1 < s.size())
s = s.substr(pos + 1);
n++;
}
n++;
return n;
}
void PrintString(string s)
{
cout << s << endl;
}
int main() {
string s;
getline(cin, s);
string s1, s2;
s1 = s.substr(0, s.find('-'));
s2 = s.substr(s.find('-') + 1);
int n1 = count(s1);
int n2 = count(s2);
string allString = "345678910JQKA2";
string MAX = "joker JOKER";
if(s1 == MAX)
PrintString(s1);
else if(s2 == MAX)
PrintString(s2);
else if(n1 == n2)
{
string f1 = s1.substr(0, s1.find(' '));
cout << f1 << endl;
string f2 = s2.substr(0, s2.find(' '));
cout << f2 << endl;
if(allString.find(f1) > allString.find(f2))
PrintString(s1);
else
PrintString(s2);
}
else if(n1 == 4)
PrintString(s1);
else if(n2 == 4)
PrintString(s2);
else
cout << "ERROR!" << endl;
return 0;
}
11.请设计一个高效算法,再给定的字符串数组中,找到包含” Coder ”的字符串(不区分大小写),并将其作为一个新的数组返回。结果字符电的顺序按照” Coder ”出现的次数递减排列,若两个串中” Coder ”出现的次数相同,则保持他们在原数组中的位置关系。给定一个字符串数组 A 和它的大小 n ,请返回结果数组。
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int CoderNumber(string str)
{
int count = 0;
int pos = 0;
transform(str.begin(), str.end(), str.begin(), ::tolower);
while(str.find("coder") != string::npos)
{
pos = str.find("coder");
count++;
if(pos + 6 < str.size())
str = str.substr(pos + 6);
else
break;
}
return count;
}
int main() {
int n = 3;
string String_Num[3] = {"i am a coder", "coder Coder", "Code"};
int a[3];
for(int i = 0; i < n; i++)
a[i] = CoderNumber(String_Num[i]);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n - i - 1; j++)
{
if(a[j] < a[j + 1])
{
int Num_temp = a[j];
a[j] = a[j + 1];
a[j + 1] = Num_temp;
string String_temp = String_Num[j];
String_Num[j] = String_Num[j + 1];
String_Num[j + 1] = String_temp;
}
}
}
for(int i = 0; i < n; i++)
{
if(a[i] != 0)
cout << String_Num[i] << endl;
}
return 0;
}
12.在4x4的棋盘上摆满了黑白棋子,黑白两色的位置和数目随机其中左上角坐标为(1,1)右下角坐标为(4,4),现在依次有一些翻转操作,要对一些给定支点坐标为中心的上下左右四个棋子的颜色进行翻转,请计算出翻转后的棋盘颜色。给定两个数组 A 和 f ,分别为初始棋盘和翻转位置。其中翻转位置共有3个。请返回翻转后的棋盘。
例:输入
0011
1010
0110
0010
22
33
44
输出
0111
0010
0110
0010
#include <iostream>
using namespace std;
int main() {
int a[5][5] = {{0, 0, 0, 0, 0},
{0, 0, 0, 1, 1},
{0, 1, 0, 1, 0},
{0, 0, 1, 1, 0},
{0, 0, 0, 1, 0}};
int n;
cin >> n;
int p,q;
for(int i = 0; i < n; i++)
{
cin >> p >> q;
//判断上方的棋子是否越界
if((p - 1) >= 1 && (p - 1) <= 4 && q >= 1 && q <= 4)
a[p - 1][q] = !a[p - 1][q];
//判断下方的棋子是否越界
if((p + 1) >= 1 && (p + 1) <= 4 && p >= 1 && q <= 4)
a[p + 1][q] = !a[p + 1][q];
//判断左边的棋子是否越界
if(p >= 1 && p <= 4 && (q - 1) >= 1 && (q - 1) <= 4)
a[p][q - 1] = !a[p][q - 1];
//判断右边的棋子是否越界
if(p >= 1 && p <= 4 && (q + 1) >= 1 && (q + 1) <= 4)
a[p][q + 1] = !a[p][q + 1];
}
for(int i = 1; i <= 4; i++)
{
for(int j = 1; j <= 4; j++)
cout << a[i][j];
cout << endl;
}
return 0;
}