1、01序列
对于长度为6位的一个01串,每一位都可能是0或1,一共有64种可能。它的前几个是:
000000
000001
000010
000011
000100
请按从小到大的顺序输出这64种01串。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j;
for(i = 0; i < 64; i++)
{
for(j = 5; j >= 0; j--)
// 利用右移运算依次输出每一位
printf("%d", (i >> j) & 1);
printf("\n");
}
return 0;
}
2、 矩阵转置
输入一个N*N的矩阵,将其转置后输出。要求:不得使用任何数组(就地逆置)。
#include<stdio.h>
#include<stdlib.h>
int main(){
int N;
scanf("%d",&N);
int a[N][N];
for(int i = 0;i<N;i++){
for(int j = 0;j<N;j++){
scanf("%d",&a[i][j]);
}
}
for(int i = 0;i<N;i++){
for(int j = 0;j<N;j++){
printf("%d ",a[j][i]);
}
printf("\n");
}
}
3、8进制
输入一个整数,将其转换成八进制数输出。
注意在机试中处理连续输入
#include<stdio.h>
#include<stdlib.h>
int main(){
int N;
while(scanf("%d",&N)!=EOF){
printf("%o",N);
printf("\n");
}
}
4、统计单词
编一个程序,读入用户输入的,以“.”结尾的一行文字,统计一共有多少个单词,并分别输出每个单词含有多少个字符。 (凡是以一个或多个空格隔开的部分就为一个单词)
注意单独讨论多个空格分隔的情况!
#include<stdio.h>
#include<stdlib.h>
int main(){
char s[100];
gets(s);
int a[100];
int i = 0;
int j = 0;
int len = 0;
while((s[i]!='.')){
if(s[i] == ' ' && s[i+1] != ' '){
a[j] = len;
len = 0;
j = j + 1;
}else if(s[i] == ' ' && s[i+1] == ' '){
i = i + 1;
continue;
}
else{
len = len + 1;
}
i = i + 1;
}
a[j] = len;
a[j+1] = '\0';
for(int i = 0;a[i]!='\0';i++){
printf("%d ",a[i]);
}
}
5、日期转换
给出年分m和一年中的第n天,算出第n天是几月几号。
#include<stdio.h>
#include<stdlib.h>
int table[2][12] = {{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}};
int isRunyear(int year){
if((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))
return 1;
else
return 0;
}
int main(){
int year;
int date;
int month=1,day;
while(scanf("%d %d",&year,&date)!=EOF){
month = 1;
int i = 0;
if(isRunyear(year)==1){
while(date-table[1][i]>0){
date = date - table[1][i];
i = i + 1;
month = month + 1;
}
day = date;
}else{
while(date-table[0][i]>0){
date = date - table[0][i];
i = i + 1;
month = month + 1;
}
day = date;
}
printf("%04d-%02d-%02d",year,month,day);
printf("\n");
}
}
6.大整数排序
对N个长度最长可达到1000的数进行排序。
#include<stdio.h>
#include<string.h>
int Compare(char s1[1000],char s2[1000]){
int len1 = strlen(s1);
int len2 = strlen(s2);
if(len1>len2){
return 1;
}else if(len1<len2){
return -1;
}else{
return strcmp(s1,s2);
}
}
int main(){
int n;
while((scanf("%d",&n))!=EOF){
char a[100][1000];
int i = 0;
char s[1000];
getchar();
while(n--){
gets(s);
strcpy(a[i],s);
i++;
}
int len = i;
for(int i = 0; i<len; i++){
for(int j = 0;j<len-1-i;j++){
if(Compare(a[j],a[j+1])>0){
char temp[1000];
strcpy(temp,a[j]);
strcpy(a[j],a[j+1]);
strcpy(a[j+1],temp);
}
}
}
int k = 0;
while(k<len){
puts(a[k]);
k++;
}
}
}
7.特殊排序
输入一系列整数,将其中最大的数挑出(如果有多个,则挑出一个即可),并将剩下的数进行排序,如果无剩余的数,则输出-1。
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int n;
while(scanf("%d",&n)!=EOF){
int a[1000];
int i = 0;
for(;i<n;i++){
cin >> a[i];
}
sort(a,a+n);
printf("%d\n",a[n-1]);
if(n==1){
printf("-1");
}
for(int i = 0;i<n-1;i++){
printf("%d ",a[i]);
}
printf("\n");
}
}
8.大整数加法 a+b
实现一个加法器,使其能够输出a+b的值。
#include <bits/stdc++.h>
using namespace std;
int main(){
string s1;
string s2;
while(cin>>s1>>s2){
int result[1000] = {0};
int len1 = s1.length();
int len2 = s2.length();
int len = max(len1,len2);
// 末尾相加 符合运算逻辑
reverse(s1.begin(),s1.end());
reverse(s2.begin(),s2.end());
for(int i = 0;i<=len-1;i++){
int a=0,b=0;
if(i<len1){
a=s1[i]-'0';
}
if(i<len2){
b=s2[i]-'0';
}
// 判断进位
result[i] = a+b+result[i];
result[i+1] = result[i]/10;
result[i] = result[i]%10;
}
// 如果result[len]不为0 说明进位到了这一位 故长度加一
if(result[len]!=0){
len = len + 1;
}
for(int i = len -1;i>=0;i--){
printf("%d",result[i]);
}
printf("\n");
}
}
9.成绩排序
有N个学生的数据,将学生数据按成绩从低到高排序,如果成绩相同则按姓名字符的字典序排序,如果姓名的字典序也相同则按照学生的年龄从小到大排序,并输出N个学生排序后的信息。
这道题我踩了两个坑,导致一直在查错:
①C++的string类型是不能用%s直接输出的——用.c_str()函数转换后输出
②我在while循环中改变了n的值,导致sort函数一直报错,后来先存储了n的值得以解决
#include<bits/stdc++.h>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
struct student{
string name;
int year;
int grade;
};
typedef struct student student;
bool Compare(student a,student b){
if(a.grade == b.grade){
if(a.name==b.name){
return a.year < b.year;
}else{
return a.name < b.name;
}
}
else
return a.grade < b.grade;
}
int main(){
int n;
student student_group[1000];
int i;
student stu;
while((scanf("%d",&n))!=EOF){
i = 0;
int n2 = n;
while(n2--){
cin >> student_group[i].name >> student_group[i].year >> student_group[i].grade;
i = i + 1;
}
sort(student_group,student_group+n,Compare);
for(i=0;i<n;i++){
// printf("%s %d %d",student_group[i].name.c_str(),student_group[i].year,student_group[i].grade);
cout<< student_group[i].name <<" "<< student_group[i].year << " "<< student_group[i].grade << endl;
}
}
}
10.二叉树排序
二叉树的前序、中序、后序遍历的定义: 前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树; 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树; 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。 给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{
char data;
TreeNode* leftChild;
TreeNode* rightChild;
};
void PostOrder(TreeNode* root){
if(root==NULL){
return;
}
PostOrder(root->leftChild);
PostOrder(root->rightChild);
cout << root->data;
}
TreeNode* Build(string str1,string str2){
if(str1.length()==0){
return NULL;
}
char c = str1[0];
int position = str2.find(c);
TreeNode* root = new TreeNode();
root->data = c;
root->leftChild = Build(str1.substr(1,position),str2.substr(0,position));
root->rightChild = Build(str1.substr(position+1),str2.substr(position+1));
return root;
}
int main(){
string str1,str2;
while(cin>>str1>>str2){
TreeNode* root = Build(str1,str2);
PostOrder(root);
printf("\n");
}
}
11.二叉排序树1
输入一系列整数,建立二叉排序树,并进行前序,中序,后序遍历。
这道题值得注意的是,不能在主函数中以创建新节点的方式新建root,必须以TreeNode* root = NULL;的方式;换句话说,在insert函数钟必须有创建结点的语句,否则无法递归的创造左孩子、右孩子。
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{
int data;
TreeNode* leftChild;
TreeNode* rightChild;
};
void PreOrder(TreeNode* root){
if(root==NULL){
return;
}
printf("%d ",root->data);
PreOrder(root->leftChild);
PreOrder(root->rightChild);
}
void InOrder(TreeNode* root){
if(root==NULL){
return;
}
InOrder(root->leftChild);
printf("%d ",root->data);
InOrder(root->rightChild);
}
void PostOrder(TreeNode* root){
if(root==NULL){
return;
}
PostOrder(root->leftChild);
PostOrder(root->rightChild);
printf("%d ",root->data);
}
TreeNode* Insert(TreeNode* root,int x){
if (root==NULL){
root = new TreeNode();
root->data = x;
}else if(x<root->data){
root->leftChild = Insert(root->leftChild,x);
}else if(x>root->data){
root->rightChild = Insert(root->rightChild,x);
}
return root;
}
int main(){
int n;
while(cin>>n){
TreeNode* root = NULL;
for(int i=0;i<n;i++){
int x;
cin>>x;
root = Insert(root,x);
}
PreOrder(root);
printf("\n");
InOrder(root);
printf("\n");
PostOrder(root);
printf("\n");
}
}
12 二叉排序树2
二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树: 1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值; 2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值; 3. 左、右子树本身也是一颗二叉排序树。 现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{
int data;
TreeNode* leftChild;
TreeNode* rightChild;
};
TreeNode* Insert(TreeNode* root,int x,int father){
if(root==NULL){
root = new TreeNode();
root->data = x;
printf("%d\n",father);
}else if(root->data>x){
root->leftChild = Insert(root->leftChild,x,root->data);
}else if(root->data<x){
root->rightChild = Insert(root->rightChild,x,root->data);
}
return root;
}
int main(){
int n;
while(cin>>n){
TreeNode* root = NULL;
for(int i = 0;i<n;i++){
int x;
cin >> x;
root = Insert(root,x,-1);
}
}
}
13 对称矩阵
输入一个N维矩阵,判断是否对称。
#include<bits/stdc++.h>
using namespace std;
int main(){
int N;
while(cin >> N){
int a[N][N] = {0};
for(int i = 0;i<N;i++){
for(int j = 0;j<N;j++){
scanf("%d",&a[i][j]);
}
}
int flag = 1;
for(int i = 0;i<N;i++){
for(int j = 0;j<N;j++){
if(a[i][j]!=a[j][i]){
flag = 0;
}
}
}
if(flag==1)
printf("Yes!\n");
else
printf("No!\n");
}
}
14.N阶楼梯上楼问题
一次可以走两阶或一阶,问有多少种上楼方式。
递归解法(超时):
#include<bits/stdc++.h>
using namespace std;
int climb(int n){
if (n==0 or n==1){
return 1;
}else if(n==2){
return 2;
}else{
return climb(n-1)+climb(n-2);
}
}
int main(){
int n;
while(cin>>n){
cout<<climb(n);
}
}
非递归解法,动态规划:
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long dp[100];
dp[0] = 0;
dp[1]=1;
dp[2]=2;
for(int i=3; i<=90;i++)
{
dp[i] = dp[i-1]+dp[i-2];
}
int n;
while(scanf("%d",&n)!=EOF)
{
printf("%lld\n",dp[n]);
}
}
15.遍历列表
建立一个升序链表并遍历输出。
#include<bits/stdc++.h>
using namespace std;
struct Node{
int data;
Node* next;
};
Node* Insert(Node* head,int x){
Node* temp = new Node();
temp->data = x;
Node* p = head;
while(p->next!=NULL and p->next->data<temp->data){
p = p->next;
}
temp->next = p->next;
p->next = temp;
return head;
}
int main(){
int n;
while(cin>>n){
Node* head = new Node();
for(int i = 0 ; i < n; i++){
int x;
cin>>x;
head = Insert(head, x);
}
Node* p = head->next;
while(p){
cout<<p->data<<" ";
p = p->next;
}
}
}
16.回文字符串
给出一个长度不超过1000的字符串,判断它是不是回文(顺读,逆读均相同)的。
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
while(cin>>s){
int len = s.length();
int pos1 = 0;
int pos2 = len-1;
int flag = 1;
while(pos1<=pos2){
if(s[pos1]!=s[pos2]){
flag = 0;
}
pos1++;
pos2--;
}
if(flag==1)
printf("Yes!\n");
else
printf("No!\n");
}
}
17.守形数
守形数是这样一种整数,它的平方的低位部分等于它本身。 比如25的平方是625,低位部分是25,因此25是一个守形数。 编一个程序,判断N是否为守形数。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
while(cin>>n){
int N = n*n;
int temp = N-n;
if(temp%10==0)
printf("Yes!\n");
else
printf("No!\n");
}
}
18.梅森素数
关于梅森素数。所谓梅森数,是指形如2^p-1的一类数,其中指数p是素数,常记为M(p)。如果p是素数的同时,梅森数(即2^p-1)也是素数,就称这个梅森数为梅森素数。输入一个长整型数n,输出不大于它的所有梅森素数。
#include<bits/stdc++.h>
#include<math.h>
using namespace std;
int isP(long long n){
if(n==1)
return 0;
else if(n==2)
return 1;
for(int i = 2;i<=sqrt(n);i++){
if(n%i==0){
return 0;
}
}
return 1;
}
int main(){
long long n;
cin>>n;
if(n>2){
for(int i=2;i<n;i++){
if(isP(i)){
long long N = pow(2,i)-1;
if(N>n){
break;
}else if((N<n)and isP(N)){
printf("M(%lld)=%lld\n",i,N);
}
}
}
}
}
19.找位置
对给定的一个字符串,找出有重复的字符,并给出其位置,如:abcaaAB12ab12 输出:a,1;a,4;a,5;a,10,b,2;b,11,1,8;1,12, 2,9;2,13。
#include<bits/stdc++.h>
using namespace std;
struct st{
char c;
int pos;
int cnt = 0;
int flag = 1;
};
int main(){
string s;
while(cin>>s){
int temp;
struct st st[100];
int a[100];
for(int i = 0;i<s.length();i++){
for(int j = 0;j<s.length();j++){
if(s[i]==s[j]){
temp++;
}
}
a[i] = temp;
temp = 0;
}
for(int i = 0;i<s.size();i++){
st[i].c = s[i];
st[i].pos = i;
st[i].cnt = a[i];
}
for(int i=0;i<s.size();i++){
if(st[i].flag==1 && st[i].cnt>1){
printf("%c:%d",st[i].c,st[i].pos);
for(int j = i;j<s.size();j++){
if(st[j].c == st[i].c && j!=i){
printf(",%c:%d",st[j].c,st[j].pos);
st[j].flag = 0;
}
}
printf("\n");
}
}
}
}
20.IP地址
输入一个ip地址串,判断是否合法。
本题需要注意,分割字符串最简单的时候是控制输入!
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b,c,d;
while(scanf("%d.%d.%d.%d",&a,&b,&c,&d)!=EOF){
if(a<0||a>255){
cout<<"No!"<<endl;
}else if(b<0||b>255){
cout<<"No!"<<endl;
}else if(c<0||c>255){
cout<<"No!"<<endl;
}else if(d<0||d>255){
cout<<"No!"<<endl;
}else{
cout<<"Yes!"<<endl;
}
}
return 0;
}
21.进制转换
输入一个十二进制数(字母一律小写,不超过8个字符)
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
while(cin>>s){
int ans = 0; // ans是二进制对应的十进制数
for(int i=0;i<s.size();i++){
if(s[i]>='a'&&s[i]<='b'){
ans = ans * 12;
ans = ans + s[i]-'a'+10;
printf("%d ",s[i]-'a'+10);
}else {
ans = ans * 12;
ans = ans + s[i] - '0';
printf("%d ", s[i] - '0');
}
}
// 第一行输出结束
printf("\n%d\n",ans);
// 第二行输出结束
int arr[32] = {0};
int cnt = 31;
while(ans){ // 求二进制
arr[cnt--] = ans%2;
ans/=2;
}
for(int i=0;i<32;i++){
printf("%d",arr[i]);
if(i%8==7)
printf(" ");
}
}
}
22.删除数字
感谢来自@xc889078的思路:
从最高位开始,一次向低位搜索,一旦遇到前一位(高位)的数大于当前位,则删去前一位,直到删除k个数,如果到达末尾还没有删除k个,则说明现在这个数已经是从小到大排序了,则从最低位开始删除要求的位数。
使用C++的erase函数可以方便的清除n位字符;
#include<bits/stdc++.h>
using namespace std;
int main(){
string a;
cin >> a;
int n;
cin >> n;
int len = a.size();
while(n--){
int i = 0;
while(i<len-1 and a[i]<a[i+1]){
i++;
}
if(i==len-1){
a.erase(len-1,1);
len--;
}else{
a.erase(i,1);
len--;
}
}
cout << a;
}
23.排序去重
输入一个长度为n的数组,先将其进行排序输出,然后对排序后的结果去重再次输出
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
printf("\n");
for(int i =0;i<n;i++){
if(a[i]==a[i+1])
continue;
cout<<a[i]<<" ";
}
printf("\n");
}
24.十进制加密
输入一个占32比特位的十进制正整数,按下述规则输出加密后的十进制整数:
设这个整数的二进制表示为x x x x p p p p x x x x e e e e x x x x e e e e x x x x e e e e ,将其中标记为e的均左移8位,标记为p的右移24位,标记为x的位置不变,输出加密后的数的十进制表示
本题学习N诺官方解法
#include<iostream>
#include<algorithm>
using namespace std;
long long n;
int main() {
while(~scanf("%lld",&n)){
long long e = (n & 0x000f0f0f) , p = (n & 0x0f000000) , x = n - e -p ;
printf("%lld\n",(e << 8) + (p >> 24) + x);
}
}
25.最长&最短文本
输入多行字符串,请按照原文本中的顺序输出其中最短和最长的字符串,如果最短和最长的字符串不止一个,请全部输出。
#include<bits/stdc++.h>
using namespace std;
bool f(string s1,string s2){
return s1.size()<s2.size();
}
int main(){
string array[100];
string s;
int i = 0;
while(cin>>s){
array[i] = s;
i++;
}
sort(array,array+i,f);
int min = array[0].size();
int max = array[i-1].size();
for(int j=0;j<i;j++){
if(array[j].size()==min or array[j].size()==max)
cout << array[j]<<endl;
}
}
26.单词个数统计
从键盘输入一行英文句子,句子中只有英文单词和空格,每个单词之间用若个空格隔开,英文单词由大小写字母组成,编程完成以下任务:
(1)统计并输出此句子中英文字母的个数;(10分)
(2)统计并输出此句子中单词的个数;(10分)
(3)查找此句子中出现次数最多的字母(不区分大小写,大小写字母是相同的)及次数。当出现最多的字符不止一个时,都能找到,并输出找到的所有字母及次数。(输出字母时大小写均可) (20分)
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
getline(cin,s);
int cnt_char = 0;
int cnt_word = 1;
int count[1000] = {0};
for(int i=0;i<s.size();i++){
if(('a'<=s[i] and s[i]<='z') or ('A'<=s[i] and s[i]<='Z')){
cnt_char++;
}
if(s[i] == ' '){
cnt_word++;
}else{
count[s[i]]++;
}
}
int max = 0;
for(int i=0; i<1000;i++){
if(count[i] > max){
max = count[i];
}
}
cout << cnt_char << endl;
cout << cnt_word << endl;
char c = 0;
for(int i = 0;i<1000;i++){
if(count[i] == max){
c = (char)i;
cout<<c<<" ";
}
}
printf("\n");
cout << max << endl;
}
在本题中,使用了C++的数组来模拟哈希表,参考的是这篇文章:
找出字符串中出现次数最多的字符 c语言_百度知道 (baidu.com)https://zhidao.baidu.com/question/941747427948204052.html
27.最小年龄的3个职工
职工有职工号,姓名,年龄.输入n个职工的信息,找出3个年龄最小的职工打印出来。
#include<bits/stdc++.h>
using namespace std;
struct employee{
int No;
string name;
int age;
};
int f(struct employee e1,struct employee e2){
if(e1.age<e2.age){
return 1;
}else if(e1.age>e2.age){
return 0;
}else if(e1.No < e2.No){
return 1;
}else if(e1.No > e2.No){
return 0;
}else if(e1.name<e2.name){
return 1;
}else if(e1.name>e2.name){
return 0;
}
}
int main(){
int N;
while(cin>>N){
struct employee array[30];
for(int i =0;i<N;i++){
struct employee e;
cin>>e.No>>e.name>>e.age;
array[i] = e;
}
sort(array,array+N,f);
for(int i =0;i<min(N,3);i++){
cout<<array[i].No<<" "<<array[i].name<<" "<<array[i].age<<endl;
}
}
}