菜鸟一枚,勿喷!!!
练习一
题目1
问题表述:
第一行输入一个数n,1 <= n <= 1000,下面输入n行数据,每一行有两个数,分别是x y。输出一组x y,该组数据是所有数据中x最小,且在x相等的情况下y最小的。
输入描述:
输入有多组数据。
每组输入n,然后输入n个整数对。
输出描述:
输出最小的整数对。
#include<bits/stdc++.h>
using namespace std;
struct node{
int x,y;
};
bool cmp(node x, node y){ //按照从小到大排序,优先排x,然后是y
return (a.x != b.x) ? (a.x < b.x) : (a.y < b.y);
}
int main()
{
int n;
cin>>n;
vector<node> v;
for(int i = 0; i < n; i++){
int x,y;
cin>>x>>y;
v.push_back({x,y});
}
sort(v.begin(), v.end(), cmp);
cout<<v[0].x<<" "<<v[0].y<<endl;
}
题目2
问题表述:
输入一个32位整数,输出该数二进制表示中1的个数
数据范围-100-100
#include<bits/stdc++.h>
using namespace std;
int main()
{
long m,res=0;
cin>>m;
while(m != 0)
{
if(m % 2 == 1)
res++;
m = floor(m/2);
}
cout<<res;
}
题目3
问题表述:
让我们用字母 B 来表示“百”、字母 S 表示“十”,用 12…n 来表示不为零的个位数字 n(<10),换个格式来输出任一个不超过 3 位的正整数。例如 234 应该被输出为 BBSSS1234,因为它有 2 个“百”、3 个“十”、以及个位的 4。
输入格式:
每个测试输入包含 1 个测试用例,给出正整数 n(<1000)。
输出格式:
每个测试用例的输出占一行,用规定的格式输出 n。
#include<bits/stdc++.h>
using namespace std;
int main()
{
vector<char> v1; //使用vector存
int n,b,s,g,i; //b代表百位,s代表十位。g代表个位
cin>>n;
b = n/100;
s = n%100/10;
g = n%10;
// cout<<b<<" "<<s<<" "<<g;
for(; b > 0; b--) //存入百位数的B
{
v1.push_back('B');
}
for(; s > 0; s--) //存入十位数的S
{
v1.push_back('S');
}
for(i = 1 ; i <= g; i++)//存入个位数的对应数字
{
v1.push_back('0' + i);
}
for(i = 0; i < v1.size(); i++)
{
cout<<v1[i]; //遍历输出v1的各项
}
}
题目4
问题表述:给定一个 k 位整数,请编写程序统计每种不同的个位数字出现的次数。例如:给定 N=100311,则有 2 个 0,3 个 1,和 1 个 3。
输入格式:
每个输入包含 1 个测试用例,即一个不超过 1000 位的正整数 N。
输出格式:
对 N 中每一种不同的个位数字,以 D:M 的格式在一行中输出该位数字 D 及其在 N 中出现的次数 M。要求按 D 的升序输出。
#include<bits/stdc++.h>
using namespace std;
int main()
{
char num[1000];
int res[10]={0},i,j;
cout<<"输入整数N:";
cin>>num;
for(i = 0; i < strlen(num); i++)
{
res[num[i] - '0']++;
}
for(i = 0; i < 10; i++)
{
cout<<i<<":"<<res[i]<<endl;
}
}
题目5
问题表述:给定一个 k+1 位的正整数 N,写成 ak ⋯a1 a0 的形式,其中对所有 i 有 0≤ai <10 且 ak >0。N 被称为一个回文数,当且仅当对所有 i 有 ai =ak−i 。零也被定义为一个回文数。非回文数也可以通过一系列操作变出回文数。首先将该数字逆转,再将逆转数与该数相加,如果和还不是一个回文数,就重复这个逆转再相加的操作,直到一个回文数出现。如果一个非回文数可以变出回文数,就称这个数为延迟的回文数。(次数小于等于10),给定任意一个正整数,本题要求你找到其变出的那个回文数。4321就是个回文数。
输入格式:
输入在一行中给出一个不超过1000位的正整数。
输出格式:
对给定的整数,一行一行输出其变出回文数的过程。
#include<bits/stdc++.h>
using namespace std;
string add(string s) {
string t,res;
t = s;
reverse(t.begin(),t.end());
int i,c = 0,num; //C是进位
for(int i = 0; i < s.length(); i++) {
num = s[i] - '0' + t[i] - '0' + c;
c = 0;
if(num >= 10) {
c = 1;
num -= 10;
}
res += char(num + '0');
}
if(c == 1)
res += '1';
reverse(res.begin(),res.end());
return res;
}
int main() {
string s,t;
cin>>s;
int count = 0;
while(count < 10) {
t = s;
reverse(t.begin(),t.end()); //倒转
if(s == t) {
cout<<s<<"是回文数"<<endl;
break;
} else {
cout<<s<<"+"<<t<<'='<<add(s)<<endl;
s = add(s);
}
count++;
}
if(count == 10) {
cout<<"未找到"<<endl;
}
}
题目6
问题表述:如果某个数 K 的平方乘以 N 以后,结果的末尾几位数等于 K,那么就称这个数为“N-自守数”。例如 3×92^2 =25392,而 25392 的末尾两位正好是 92,所以 92 是一个 3-自守数。本题就请你编写程序判断一个给定的数字是否关于某个 N 是 N-自守数。
输入格式:
输入在第一行中给出正整数 M(≤20),随后一行给出 M 个待检测的、不超过 1000 的正整数。
输出格式:
对每个需要检测的数字,如果它是 N-自守数就在一行中输出最小的 N 和 N*K^2 的值,以一个空格隔开;否则输出 No。注意题目保证 N<10。
#include<bits/stdc++.h>
using namespace std;
/*
1
92s
*/
int main()
{
int m;
cin>>m;
for(int i = 0; i < m; i++){
int n;
cin>>n;
int t = n,a = 1,N = 1;
while(t){ //核心代码:利用t求出a的位数,方便后续做区域处理
a*=10; //a是后来对计算求出来的很大的值求余运算的模的大小
t/=10; //t是为了求n一共有几位,t有几位,a就乘几个10,最后取余的时候就对a取余
}
while(N < 10){ //题中说了最多10次
if((n*n*N) % a == n)
{
cout<<N<<" "<<N*n*n<<endl;
break;
}else{
N++;
}
}
if(N == 10)
{
cout<<"no";
}
}
}
题目7
问题表述:下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1;B-2;C-3;D-4;请同学们自己作答,每两日一换。谢谢合作!!~”—— 老师们为了促进学生学习也是拼了…… 本题就要求你写程序把一系列题目的答案按照卷子上给出的对应关系翻译成 wifi 的密码。这里简单假设每道选择题都有 4 个选项,有且只有 1 个正确答案
输入样例:
8
A-T B-F C-F D-F
C-T B-F A-F D-F
A-F D-F C-F B-T
B-T A-F C-F D-F
B-F D-T A-F C-F
A-T C-F B-F D-F
D-T B-F C-F A-F
C-T A-F B-F D-F
输出样例:
13224143
#include<bits/stdc++.h>
using namespace std;
/*
8
A-T B-F C-F D-F
C-T B-F A-F D-F
A-F D-F C-F B-T
B-T A-F C-F D-F
B-F D-T A-F C-F
A-T C-F B-F D-F
D-T B-F C-F A-F
C-T A-F B-F D-F
*/
int main()
{
int n;
string s,res;
cin>>n;
getchar();
for(int i = 0; i < n; i++){
getline(cin,s);
for(int j = 2; j < s.length(); j++)
{
if(s[j] == 'T')
{
res+=char(s[j-2]-'A'+1+'0'); //其实这里用int数组存会更好,用num[100]存,然后遍历输出
}
}
}
cout<<res;
return 0;
}
练习二
题目1
问题表述:正整数 A 的“DA(为 1 位整数)部分”定义为由 A 中所有 DA 组成的新整数 PA。例如:给定 A=3862767,DA=6,则 A 的“6 部分”PA 是 66,因为 A 中有 2 个 6。
现给定 A、DA、B、DB,请编写程序计算 PA+PB。
输入格式:
输入在一行中依次给出 A、DA、B、DB,中间以空格分隔,其中 0<A,B<1010。
输出格式:
在一行中输出 PA+PB 的值。
法1:
#include<bits/stdc++.h>
using namespace std;
/*
23322 2 123442 4
*/
int main(){
cout<<"go";
char s[25];
char strA[10];
char strB[10];
gets(s);
int len = strlen(s);
int i,j,k,m,n;
int pA = 0,pB = 0;
while(s[i] != ' ' && i < len){
strA[j++] = s[i++];
}
i++;
int dA = s[i++] - '0';
i++;
while(s[i] != ' ' && i < len){
strB[k++] = s[i++];
}
i++;
int dB = s[i++] - '0';
for(m = 0; m < j; m++){
if(strA[m]-'0' == dA) pA = pA*10 + dA;
}
for(m = 0; m < k; m++){
if(strB[m]-'0' == dB) pB = pB*10 + dB;
}
cout<<pA+pB;
return 0;
}
法2:
#include<bits/stdc++.h>
using namespace std;
/*
23322 2 123442 4
*/
int main(){
char s[25];
char strA[10],strB[10];
gets(s);
int len = strlen(s);
int i = 0,j = 0,k = 0,p = 1,dA,dB,pA = 0,pB = 0;
while(s[i] && i < len){
if(s[i] == ' ')
{
i++;
p++;
}
switch(p){
case 1:{
strA[j++] = s[i++];
break;
}
case 2:{
dA = s[i++] - '0';
break;
}
case 3:{
strB[k++] = s[i++];
break;
}
case 4:{
dB = s[i++] - '0';
break;
}
}
}
for(i = 0; i < j; i++){
if(strA[i] - '0' == dA) pA = pA*10 + dA;
}
for(i = 0; i < k; i++){
if(strB[i] - '0' == dB) pB = pB*10 + dB;
}
cout<<pA<<"---"<<pB<<endl;
cout<<pA+pB<<endl;
//验证
// cout<<"stra:";
// for(i = 0; strA[i]; i++){
// cout<<strA[i];
// }
// cout<<endl<<"dA:"<<dA<<endl;
// cout<<"strb:";
// for(i = 0; strB[i]; i++){
// cout<<strB[i];
// }
// cout<<endl<<"dB:"<<dB<<endl;
}
题目2
问题表述:按照 年年年年月月日日 格式组成的字符串 20200202 是完全对称的。给定任意一个日期,本题就请你写程序判断一下,这是不是一个对称日?
输入格式:
输入首先在第一行给出正整数 N(1<N≤10)。随后 N 行,每行给出一个日期,却是按英文习惯的格式:Month Day, Year。其中 Month 是月份的缩写,对应如下:
一月:Jan
二月:Feb
三月:Mar
四月:Apr
五月:May
六月:Jun
七月:Jul
八月:Aug
九月:Sep
十月:Oct
十一月:Nov
十二月:Dec
Day 是月份中的日期,为 [1, 31] 区间内的整数;Year 是年份,为 [1, 9999] 区间内的整数。
输出格式:
对每一个给定的日期,在一行中先输出 Y 如果这是一个对称日,否则输出 N;随后空一格,输出日期对应的 年年年年月月日日 格式组成的字符串。
输入样例:
5
Feb 2 2020
Mar 7 2020
Oct 10 101
Nov 21 1211
Dec 29 1229
输出样例:
Y 20200202
N 20200307
Y 01011010
Y 12111121
N 12291229
#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
using namespace std;
/*
输入样例:
5
Feb 2 2020
Mar 7 2020
Oct 10 101
Nov 21 1211
Dec 29 1229
输出样例:
Y 20200202
N 20200307
Y 01011010
Y 12111121
N 12291229
*/
int main() {
const char* month[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
int N,i;
cin>>N;
int date,year;
char a[8];
char res[N][10]; //res存储最后的N个结果
for(i = 0; i < N; i++) {
int num[8],j;
scanf("%s %d %d", a, &date, &year); //格式化输入数据
for(j = 0; j < 12; j++) {
if(strcmp(month[j],a) == 0) //用month数组对应相应的月份
break;
}
int m = ++j; //拿到月份
for(j = 3; j >= 0; j--) { //输人年份到num中
num[j] = year % 10;
year /= 10;
}
for(j = 5; j > 3; j--) { //输人月份到num中
num[j] = m % 10;
m /= 10;
}
for(j = 7; j > 5; j--) { //输人date到num中
num[j] = date % 10;
date /= 10;
}
int flag = 1; //认为flag=1代表Y
for(j = 0; j < 4; j++) {
if(num[j] != num[7-j]) {
flag = 0;
break;
}
}
if(flag == 1) {
res[i][0] = 'Y';
}else{
res[i][0] = 'N';
}
res[i][1] = ' ';
for(j = 2; j < 10; j++){
res[i][j] = num[j-2] + '0'; //存储当前次结果进入res二维数组
}
}
for(i = 0; i < N; i++){ //输出result
for(int j = 0; j < 10; j++){
cout<<res[i][j];
}
cout<<endl;
}
}
题目3
问题表述:给定一个单链表 L,请编写程序将 L 中所有的链接反转。
输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数,即正整数N (≤10^5)。结点的地址是5位非负整数,NULL地址用−1表示。
接下来有N行,每行格式为:
Address Data Next
其中Address是结点地址;Data是该结点保存的数据,为不超过10^5的正整数;Next是下一结点的地址。题目保证给出的链表上至少有两个结点。
输出格式:
对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。
#include<stdio.h>
#include<stdlib.h>
/*
10 5
100 1 23
10 2 100
23 5 44
45 3 -1
44 6 45
*/
typedef struct INode {
int addR;
int data;
int next;
} lNode, *list;
int main() {
int firstA,n;
scanf("%d %d", &firstA, &n); //第一行输入初始地址和共多少个节点
list L;
L = (list)malloc( (n+1) * sizeof(lNode) ); //给各个节点分配空间
int* r;
r = (int *)malloc( (n+1) * sizeof(int) ); //r的内容顺序存放着单链表节点的正向顺序
for(int i = 0; i < n; i++) {
scanf("%d %d %d", &L[i].addR, &L[i].data, &L[i].next);
if(L[i].addR == firstA) r[0]=i; //一旦i节点对应的addR等于单链表首地址,将i存入r[0]
}
//调整链表顺序
for(int i = 0; i < n-1; i++) {
for(int j = 0; j < n; j++) {
if(L[j].addR == L[r[i]].next) { //当哪一个j的addR等于上一个节点对应的next,将新节点j存入r数组
r[i+1] = j;
break;
}
}
}
r[n]=n;
L[n].addR=-1;
//逆序输出节点
printf("res:\n");
for(int i = n-1 ; i > 0; i--){
printf("%d %d %d\n",L[r[i]].addR, L[r[i]].data,L[r[i-1]].addR);
}
printf("%d %d -1\n",L[r[0]].addR, L[r[0]].data);
return 0;
}
题目4
问题表述:把 2019 各个数位上的数字 2、0、1、9 作为一个数列的前 4 项,用它们去构造一个无穷数列,其中第 n(>4)项是它前 4 项之和的个位数字。例如第 5 项为 2, 因为 2+0+1+9=12,个位数是 2。
本题就请你编写程序,列出这个序列的前 n 项。
输入格式:
输入给出正整数 n(≤1000)。
输出格式:
在一行中输出数列的前 n 项,数字间不要有空格。
输入样例:
10
输出样例:
2019224758
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,sum;
cin>>n;
int a[n],i;
a[0] = 2;
a[1] = 0;
a[2] = 1;
a[3] = 9;
sum = a[0] + a[1] + a[2] + a[3];
for(i = 4; i < n; i++){
a[i] = sum % 10;
sum += a[i] - a[i-4];
}
for(i = 0; i < n; i++){
cout<<a[i]<<" ";
}
}
题目5
问题表述:计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。
输入描述:
输入一行,代表要计算的字符串,非空,长度小于5000。
输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。
#include<bits/stdc++.h>
using namespace std;
int main(){
char s[5010];
gets(s);
int res, len = strlen(s),i;
for(i = len - 1; i>=0 && s[i] != ' '; i--){
res++;
}
cout<<res;
return 0;
}
题目6
问题表述:输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
保证输入的整数最后一位不是0。
输入描述:
输入一个int型整数
输出描述:
按照从右向左的阅读顺序,返回一个不含重复数字的新的整数
示例:
输入:
9876673
输出:
37689
#include<bits/stdc++.h>
using namespace std;
int main(){
int m,re = 0;
cin>>m;
int a[10] = {0};
while(m>0){
if(!a[m%10]){
a[m%10] = 1;
cout<<m%10;
}
m /= 10;
}
return 0;
}
题目7
问题表述:给定一个数字序列A0,A2,…,An,求i,j(1<=i<=j<n),使得Ai+…Aj最大,输出这个最大和。
样例
-2 11 -4 13 -5 -2
显然 11 + (-4) + 13 = 20 为和最大的选取情况,因此最大和为20
#include<bits/stdc++.h>
using namespace std;
/*
6
-2 11 -4 13 -5 -2
*/
int main(){
int n,i,j,sum = 0,max = -999999,start,end;
cin>>n;
int num[n];
for(i = 0; i < n; i++){
cin>>num[i];
}
for(i = 0; i < n; i++){
for(j = i; j < n; j++){
sum += num[j];
if(sum > max){
start = i;
end = j;
max = sum;
}
}
sum = 0;
}
cout<<max;
}
题目8
问题表述:功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
最后一个数后面也要有空格
输入描述:
输入一个long型整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。
示例:
输入:
180
输出:
2 2 3 3 5
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
long n;
while(cin>>n){
int i = 2;
for(i; i<sqrt(n)+1; i++){
while(n%i == 0){ //对n从2开始依此判断是不是n的因子,要重复判断,比如对n=180,i=2要判断两次,然后i才可以自增
cout<<i<<' ';
n /= i;
}
}
if(n>1){
cout<<n;
}
}
return 0;
}
练习三
题目1
问题表述:给定一个长度为 n的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。
输入格式
第一行包含两个整数 n和 k。
第二行包含 n 个整数(所有整数均在 1∼10^9范围内),表示整数数列。
输出格式
输出排列后序列。
数据范围
1≤n≤100000,
1≤k≤n
输入样例:
5
1 3 12 9 7
输出样例:
1 3 7 9 12
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
int part(int* r, int low, int hight) //划分函数
{
int i = low, j = hight, pivot = r[low]; //基准元素
while (i < j)
{
while (i < j && r[j] > pivot) //从右向左开始找一个 小于等于 pivot的数值
{
j--;
}
if (i < j)
{
swap(r[i++], r[j]); //r[i]和r[j]交换后 i 向右移动一位
}
while (i < j && r[i] <= pivot) //从左向右开始找一个 大于 pivot的数值
{
i++;
}
if (i < j)
{
swap(r[i], r[j--]); //r[i]和r[j]交换后 i 向左移动一位
}
}
return i; //返回最终划分完成后基准元素所在的位置
}
void Quicksort(int* r, int low, int hight)
{
int mid;
if (low < hight)
{
mid = part(r, low, hight); // 返回基准元素位置
Quicksort(r, low, mid - 1); // 左区间递归快速排序
Quicksort(r, mid+1, hight); // 右区间递归快速排序
}
}
/*
5
1 3 12 9 7
*/
int main()
{
int a[10001];
int N;
cout << "请输入要排序的数据的个数: " << endl;
cin >> N;
cout << "请输入要排序的数据: " << endl;
for (int i = 0; i < N; i++)
{
cin >> a[i];
}
cout << endl;
Quicksort(a, 0, N - 1);
cout << "排序后的序列为: " << endl;
for (int i = 0; i < N; i++)
{
cout << a[i] << " ";
}
cout << endl;
return 0;
}
题目2
问题表述:给定你一个长度为 n的整数数列。
请你使用归并排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n个整数(所有整数均在 1∼10^9 范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
#include<bits/stdc++.h>
using namespace std;
void merge(int* a, int low, int mid, int hight) //合并函数
{
int* b = new int[hight - low + 1]; //用 new 申请一个辅助函数
int i = low, j = mid + 1, k = 0; // k为 b 数组的小标
while (i <= mid && j <= hight)
{
if (a[i] <= a[j])
{
b[k++] = a[i++]; //按从小到大存放在 b 数组里面
}
else
{
b[k++] = a[j++];
}
}
while (i <= mid) // j 序列结束,将剩余的 i 序列补充在 b 数组中
{
b[k++] = a[i++];
}
while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中
{
b[k++] = a[j++];
}
k = 0; //从小标为 0 开始传送
for (int i = low; i <= hight; i++) //将 b 数组的值传递给数组 a
{
a[i] = b[k++];
}
}
void mergesort(int* a, int low, int hight) //归并排序
{
if (low < hight)
{
int mid = (low + hight) / 2;
mergesort(a, low, mid); //对 a[low,mid]进行排序
mergesort(a, mid + 1, hight); //对 a[mid+1,hight]进行排序
merge(a, low, mid, hight); //进行合并操作
}
}
/*
5
3 1 2 4 5
*/
int main()
{
int n;
cout << "请输入数列中的元素个数 n 为:" << endl;
cin >> n;
int a[n];
cout << "请依次输入数列中的元素:" << endl;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
mergesort(a, 0, n-1);
cout << "归并排序结果" << endl;
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
cout << endl;
return 0;
}
题目3
问题表述:英国天文学家爱丁顿很喜欢骑车。据说他为了炫耀自己的骑车功力,还定义了一个“爱丁顿数” E ,即满足有 E 天骑车超过 E 英里的最大整数 E。据说爱丁顿自己的 E 等于87。
现给定某人 N 天的骑车距离,请你算出对应的爱丁顿数 E(≤N)。
输入格式:
输入第一行给出一个正整数 N (≤105 ),即连续骑车的天数;第二行给出 N 个非负整数,代表每天的骑车距离。
5
2 3 4 1 5
输出格式:
在一行中给出 N 天的爱丁顿数。
#include<bits/stdc++.h>
using namespace std;
bool cmp(int a, int b){
return a>b;
}
/*
数据存入数组a,并从大到小排序(下标从1开始算),如果第N个数等于或小于a[N],就说明N比临界值多1(题目要求是超出)
5
2 3 4 1 5
*/
int main(){
int n, i;
cin>>N;
int a[N] = {0};
for(i = 1; i <= N; i++){
cin>>a[i];
}
sort(a+1, a+N+1, cmp); //逆序排序
for(i = 1; i <= N; i++){
if(i >= a[i])
break;
}
cout<<i-1;
return 0;
}
题目4
问题表述:文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示。例如 ccccc 就用 5c 来表示。如果字符没有重复,就原样输出。例如 aba 压缩后仍然是 aba。
解压方法就是反过来,把形如 5c 这样的表示恢复为 ccccc。
本题需要你根据压缩或解压的要求,对给定字符串进行处理。这里我们简单地假设原始字符串是完全由英文字母和空格组成的非空字符串。
输入格式:
输入第一行给出一个字符,如果是 C 就表示下面的字符串需要被压缩;如果是 D 就表示下面的字符串需要被解压。第二行给出需要被压缩或解压的不超过 1000 个字符的字符串,以回车结尾。题目保证字符重复个数在整型范围内,且输出文件不超过 1MB。
输出格式:
根据要求压缩或解压字符串,并在一行中输出结果。
输入样例 1:
C
TTTTThhiiiis isssss a tesssst CAaaa as
输出样例 1:
5T2h4is i5s a3 te4st CA3a as
#include<bits/stdc++.h>
#include <string>
using namespace std;
//转换数字成字符串
string re_s(int n){
int i;
string re;
while(n>0){
re += (n % 10 +'0');
n /= 10;
}
reverse(re.begin(),re.end()); //逆序re
return re;
}
/*
C
TTTTThhiiiis isssss a tesssst CAaaa as
D
5T2h4is i5s a3 te4st CA3a as
*/
int main(){
char c;
cin>>c;
getchar(); //用来吃掉输入c敲入的回车
string s;
getline(cin,s); //cin只能获取到空格停止,而getline可以获取这一整行
int i = 10;
//压缩
if(c == 'C'){
for(i = 0; i < s.size(); i++){
if(s[i] == s[i+1]){
int j = i+1;
while(j<s.size() && s[j] == s[i]) j++;
int n = j-i;
string re = re_s(n); //将重复的次数变成字符串
re += s[i]; //补充字符
s.replace(i,j-i,re);
}
}
cout<<s;
}
else{ //解压
if(s.length() == 0) cout<<" ";
else{
for(int i = 0; i< s.size(); i++){
if(s[i] >= '0' && s[i] <= '9'){
int j = i+1,n = 0;
n = n*10 + (s[i]-'0');
string re;
while(j < s.length() && (s[j] >= '0' && s[j] <= '9')){
n = n*10 + (s[j] - '0'); //计算重复的次数
j++;
}
for(int k = 0; k < n; k++){ //输出重复次数个s[j]该元素
re += s[j];
}
s.replace(i,j-i,re); //替换掉从i到j-i的字符串
}
}
cout<<s;
}
}
return 0;
}
2014
题目1
问题表述:
编写一个程序,读入一组整数,他们的个数N也是由用户输入的,最多不会超过20.然后程序将对这个数组进行统计,把出现次数最多的那个数组元素值打印出来。如果有两个元素值出现的次数相同,即并列第一,那么只打印比较小的那个值。
输入说明:
第一行是一个整数N,N<=20;接下来有N行,每一行表示一个整数`
输出说明:
打印出出现次数最多的那个元素。
输入样本:
6
10 12 13 2 12 10
输出样本:
10
#include<stdio.h>
#define N 20;
/*
输入样本:
6
10 12 13 2 12 10
*/
int main()
{
int n,max,i,res;
printf("请输入整数个数:");//不超过20个
scanf("%d",&n);
int a[n];
//数据整数的数据,并留存其中的最大值max
for(i = 0; i < n; i++)
{
scanf("%d", &a[i]);
if(i == 0)
max = a[i];
else{
if(a[i] > max)
max = a[i];
}
}//max为输入数据中的最大值
//建立一个数组count,长度为max,记录整数的出现次数
int count[max+1]={0};
for(i = 0; i < n; i++)
{
count[a[i]]++;
}
//遍历count数组,找到其中出现次数最多的数(输入的整数),也就是对应count数组中的序号,如果有次数相同的,输出小的哪一个数
int temp = 1;
for(i = 0; i < max; i++)
{
if(count[i] > 0)
{
if(temp == 1)//第一次进入
{
res = i;
temp--;
}
if(count[i] > count[res]) //留存出现次数多的,存在res中
{
res = i;
}
}
}
printf("%d", res); //输出结果
}
题目2
问题表述:输入n行m列的螺旋矩阵,输出r行c列。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1004;
int a[maxn][maxn];
/**
10
4
10
4
**/
int main()
{
int n, m; //螺旋矩阵的行列
int r, c; //期望看到的行列
cin>>n>>m>>r>>c;
int num = n * m;
int x = 0, y = 0, tot = 1;
a[x][y] = 1;
while(tot < num)
{
while(y + 1 < m && !a[x][y+1]) a[x][++y] = ++tot; //right
while(x + 1 < n && !a[x+1][y]) a[++x][y] = ++tot; //down
while(y - 1 >= 0 && !a[x][y-1]) a[x][--y] = ++tot; //left
while(x - 1 >= 0 && !a[x-1][y]) a[--x][y] = ++tot; //up
}
// /*
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
printf("%4d", a[i][j]);
printf("\n");
}
// */
printf("%d", a[r-1][c-1]);
return 0;
}
题目3
问题描述:世界杯小组赛(胜得3分,平得1分,负不得分),计算每个队的积分并按排名先后输 岀,若积分相同,财按净荣数排序(保证积分相等时输入的净球数不相等)。输入M个队, 出线队N个,输出出线的队伍的排名、名称、积分、净球数。
输入说明 名称 胜 平 负 进球数 负球数
输入样本:
4 2
德国 1 1 0 9 3
俄罗斯 1 0 0 2 1
威尔士 1 1 1 10 2
芬兰 0 1 0 3 3
输出样本:
1 威尔士
2 德国
#include<stdio.h>
#include<string.h>
#define M 100
struct WorldCup
{
char country[10]; //名字
int win; // 净球数
int integrate; //积分
int grade; //排名
};
int main()
{
int n,m,i,j,s1,s2,s3,w1,w2,temp;
printf("请输入队伍数和期望结果队伍数:");
scanf("%d %d", &n, &m);
WorldCup w[n];
for(i = 0; i < n; i++)
{
scanf("%s", &w[i].country);
scanf("%d %d %d", &s1, &s2, &s3);
w[i].integrate = 3*s1+s2;
scanf("%d %d", &w1, &w2);
w[i].win = w1-w2;
}
WorldCup exchange,max_now;
for(i = 0; i < n; i++)
{
temp = i;
for(j = i+1; j < n; j++)
{
if((w[j].integrate > w[i].integrate) || (w[j].integrate == w[i].integrate && w[j].win > w[i].win) )
{
temp = j;
}
}
exchange = w[i];
w[i] = w[temp];
w[temp] = exchange;
w[i].grade = i+1;
}
for(i = 0; i < m; i++)
{
printf("%-2d %-10s %-2d %-2d\n", w[i].grade, w[i].country, w[i].integrate, w[i].win );
}
}
/**
输入样本:
4 2
德国 1 1 0 9 3
俄罗斯 1 0 0 2 1
威尔士 1 1 1 10 2
芬兰 0 1 0 3 3
**/
题目4
问题描述:对于给定的字符序列,从左至右将所有数字字符取出拼接成一个无符号整数(字符序列 长度小于100,拼接出的整数小于231),计算并输出该整数的最大因子
输入说明
有多组数据;每组数据为一行字符序列,当输入一个空行时表示输入结束。
输岀说明
对每个字符序列,求出所得整数的最大因子I若字符序列中没有数字或找出的整数为0, 则输出0.每个整数占一行输出。
输入样本:
3
sdf0ejg3.f?9f
?4afd0s%2d79*(g
abcde
输出样本
13
857
0
#include<stdio.h>
#include<string.h>
#define M 100
/*
输入样本:
3
sdf0ejg3.f?9f
?4afd0s%2d79*(g
abcde
*/
int main() {
int n,i,j,temp;
printf("请输入字符序列行数:");
scanf("%d", &n);
char c[n][100];
int a[n];
//输入字符序列
for(i = 0; i < n; i++) {
scanf("%s", &c[i]);
}
//找出每一个字符序列对应的数字,并存入a[n]中
for(i = 0; i < n; i++) {
a[i] = 0;
for(j = 0; j < 100; j++) {
if(c[i][j] == '\0') break;
if(c[i][j] <= '9' && c[i][j] >= '0') {
a[i] = a[i] * 10 + c[i][j] - '0';
}
}
}
//求每个a[i]对应的最大的因子
for(i = 0; i < n; i++)
{
temp = 1;
do{
temp++;
}while(a[i] % temp != 0);
printf("%d\n",a[i] / temp);//输出这个a[i]对应的最大因子
}
}
题目4
问题描述:请写一个程序,对于_个浏行川列的(1SQ0)的方阵,求其每一行,每一列及主对角 线元素之和,最后按照从大到小的顺序依次输出。
输入说明
共一组数据,输入的第一行为一个正整数,表示爪,接下来的印行,每行m个整数表示 方阵元素。
输出说明
从大到小排列的一行整数,每个整数后跟一个空格,最后换行。
输入样本:
4
15 8 -2 6
31 24 18 71
-3 _9 27 13
17 21 38 69
输出样本:
159 145 144 135 81 60 44 28 27
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define M 100
/*
4
15 8 -2 6
31 24 18 71
-3 -9 27 13
17 21 38 69
*/
int main()
{
int n,i,j;
printf("输入行列数:");
scanf("%d", &n);
int a[n][n];
int b[24] = {0};
//从键盘获取数据
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
scanf("%d", &a[i][j]);
}
}
//收集每一行每一列以及每一列还有斜对角之和
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
b[i] += a[i][j];
b[i+n] += a[j][i];
}//收集b0-b7
b[2*n] += a[i][i];
}
sort(b,b + 2*n + 1);
for(i = 2*n; i >= 0; i--)
{
printf("%d ",b[i]);
}
}
2015
题目1
问题描述:请写一个程序,判断给定整数序列能否构成等差数列
输入说明
多组数据,每组输入数据由两行构成,第一行只有一个整数n «1000), 表示序列长度(即序列中整数的个数,0表示输入结束),第二行为n个整数, 每个整数的取值区间都为[-32768-一-32767] -> (int),整数之间以空格或挑格间隔。
输出说明
对于每一组数据,输出一个yes或no,表示该序列能否构成等差数列。
输入样本:
6
23 15 4 18 35 11
3
3 1 2
0
输出样本:
no
yes
#include<bits/stdc++.h>
using namespace std;
bool cmp(int a,int b){
return a<b;
}
/*
6
23 15 4 18 35 11
3
3 1 2
0
*/
int main(){
int n;
string re;
while(cin>>n != 0){
re = "yes";
int i,a[n];
for(i = 0; i < n; i++){
cin>>a[i];
}
sort(a,a+n,cmp); //按递增排序;
int d = a[1] -a[0];
for(i = 2; i < n; i++){
if(a[i] - a[i-1] != d){
re = "no";
break;
}
}
cout<<re<<endl;
}
}
题目2
问题描述:任意输入一个三位数,判断该书是否是水仙花数。若是输出“yes”,否则输出“no”。
#include<bits/stdc++.h>
using namespcace std;
int main(){
int x;
int a,b,c; //分别代表个位十位百位
cin>>x;
a = x % 10;
b = x / 10 % 10;
c = x / 100;
if( a * a * a + b * b * b + c * c * c == x){
cout<<"yes"<<endl;
}else{
cout<<"no";
}
return 0;
}
题目3
Arnold变换是一种常见的图像置乱技术,Arnold变换定义如下: .
对任意N乘N矩阵(素有元素相同的矩阵除外)设i, J为矩阵元素的初始下标,经过Arnold 变换后行下标为i’,j’, 其满足下式
i’ = (i+j) mod N
j '= (i+2j) mod N
i, j:0, 1, 2,… N-1
输入说明
对输入的每一个N,给出N*N矩阵的Arnold变换的周期T
输入样本:
3
8
0
输出样本
4
6
#include<bits/stdc++.h>
using namespace std;
/*
输入:
3
8
0
*/
int main(){
int N;
while(cin>>N != 0){ //N为0停止
int i = 0,j = 1,temp; //默认i=0,j=1
temp = i;
i = (i + j) % N;
j = ( temp + 2*j) % N;
int times = 1;
while(i != 0 || j != 1){
temp = i; //将i保存下来,因为下一跳语句i会变
i = ( i + j ) % N;
j = ( temp + 2*j ) % N;
times++;
}
cout<<times<<endl;
}
}
题目4
问题描述:对于一个正整数n,如果它的各位之和等于它的所有质因数的各位之和,则该数被称为 Smith 数。
例如,31257二3323*151, 31257的各位数字之和为3+1+2+5+7=18,它的所有质因数 的各位数字之和为3+3+2+3+1+5+1=18,因此,31257是一个Smith数。编写一个裡序判断输 入的正整数是不是Smith数。
输入说明
有多组数据,每组数据只有一个整数n (<100000,占一行),为0时表示输入结束。
输出说明
对于毎一组数据,输出一个yes或no (表示该数是否为Smith数)。
输入样本:
31257
123
0
输出样本:
yes
no
#include<bits/stdc++.h>
using namespace std;
#define MAX 100010
/*
Problems 4
对于一个正整数n,如果它的各位之和等于它的所有质因数的各位之和,则该数被称为 Smith 数。
例如,31257=3*3*23*151, 31257的各位数字之和为3+1+2+5+7=18,它的所有质因数 的各位数字之和为3+3+2+3+1+5+1=18,因此,31257是一个Smith数。
编写一个程序判断输入的正整数是不是Smith数。
输入说明
有多组数据,每组数据只有一个整数n (<100000,占一行),为0时表示输入结束。
输出说明
对于毎一组数据,输出一个yes或no (表示该数是否为Smith数)。
输入样本:
31257
123
0
输出样本:
yes
no
*/
int main(){
int N,a[MAX],k = 0;
while(1){
cin>>N;
if(N == 0) break;
int num_sum = 0,n = N; //num_sum代表各位数字之和
while(n != 0){
num_sum += n % 10;
n /= 10;
}
//求质因数各位之和
int z_num_sum = 0,i;
n = N;
for(i = 2; i < sqrt(N)+1; i++){
while(n%i == 0){
int j = i;
while(j != 0){
z_num_sum += j % 10;
j /= 10;
}
n /= i;
}
}
if(num_sum == z_num_sum){
a[k++] = 1;
}else{
a[k++] = 0;
}
}
for(int j = 0; j < k; j++){
if(a[j] == 1){
cout<<"yes"<<endl;
}else{
cout<<"no"<<endl;
}
}
}