2023东华大学机试OJ进阶版1-81题

东华大学研究生计算机复试进阶题

1 Huffuman树

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路:先排序。每次找两个最小的数,把其中一个置为两数之和,并累加这个和值,另一个数置为-1,然后再排序,重复操作,直到只剩下一个数。


#include<stdio.h>
#define MAX_SIZE 105

void sort(int p[], int n); 

int main() {
	int n = 0;
	int i = 0;
	int fee = 0;// 费用 
	int p[MAX_SIZE];
	
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d", &p[i]);
	
	sort(p, n);
	while (n > 1) {
		fee += (p[0] + p[1]);// 累加费用 
		p[1] = p[0] + p[1]; //p[1]变为两数之和
		p[0] = p[n - 1];//变为最大的数,后面不将它进行排序
		n--;//下次排序则少一位
		sort(p, n);
	}
	
	printf("%d\n", fee);

	return 0;
}

//排序
void sort(int p[], int n) {
	int i = 0, j = 0;
	int temp = 0;
	
	for (i = n - 1; i > 0; i--) {
		for (j = 0; j < i; j++) {
			if (p[j] > p[j + 1]) {
				temp = p[j];
				p[j] = p[j + 1];
				p[j + 1] = temp;
			} 
		}
	}
} 

2 回文数

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

哎,这题有错,但没时间改了,快复试了,还剩90多道题没刷😭

#include<stdio.h>
int isHuiwen(int n) 
{
	int a[4];
	int j;
	int flag;
	for(j=0;j<4;j++)
	{
		a[j]=n%10;
		n=n/10;
	}
	if(a[0]==a[3] && a[1]==a[2])
	{
		flag=1;
	}else{
		flag=0;
	}
	return flag;
}

int main()
{
	int i;
	int n;
	scanf("%d",&n);
	for(i=n;i<=9999;i++)
	{
		if(isHuiwen(i))
		{
			printf("%d\n",i);
		}
	}
	printf("\n");
	return 0;
}

3 字母图形

在这里插入图片描述
在这里插入图片描述

思路:规律就是a[i][j]=abs(i-j)+‘A’
在这里插入图片描述

#include <cstdio>
#include <cstring>
#include<iostream>
using namespace std;
int main()
{
	
	int n, m,cha;//n是行  m是列
	
	while (cin>>n>>m)
	{
		char a[30][30];
		memset(a, 0, sizeof(a));
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= m; j++)
			{
				cha = abs(i - j);
				for (int  k = 0; k < 26; k++)//cha必须属于26字母
				{
					if (k == cha)
					{
						a[i][j] = cha + 'A';
						//'A'+相应的数字就等于A后面的字母
					}
				}
			}
		}
		for (int i = 1; i <=n ; i++)
		{
			for (int j = 1; j <= m; j++)
			{
				cout << a[i][j];
			}
			cout << endl;
		}
	}
	return 0;
}

4 大阶乘计算

在这里插入图片描述

5 回形取数

在这里插入图片描述
在这里插入图片描述
思路:按照下,右,上,左的顺序依次输出,我写的代码里末尾有一个空格,导致输出结果不正确,剩下的由你改咯

#include<iostream>
using namespace std;
int a[200][200];
int m, n;
int main()
{
	cin >> m >> n;
	
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
		{
			cin >> a[i][j];
		}
	}
	int i=0, j=0, k=0, l=0;
	int sum = m * n;
	
	while (sum)
	{
		/*向下走*/
		for (; i < m && a[i][j] != -1; i++)
		{
			cout << a[i][j] << " ";
			a[i][j] = -1;
			sum--;
		}
		if(i>0)//此时i=m,需要减1
		i--;
		if(j<n-1&&j>=0) //此时j要往右移一个
		j++;
		/*向右走*/
		for (; j < n && a[i][j] != -1; j++)
		{
			cout << a[i][j] << " ";
			a[i][j] = -1;
			sum--;
		}
		if(j>0)
		j--;
		if(i>1&&i<m)
		i--;
		/*向上走*/
		while (i>=0 && a[i][j] != -1)
		{
			cout << a[i][j] << " ";
			sum--;
			a[i][j] = -1;
			i--;
		}
		if (i == -1)
			i++;
		if (j > 1 && j < n)
			j--;
		/*向左走*/
		while (j >= 0 && a[i][j] != -1)
		{
			cout << a[i][j] << " ";
			sum--;
			a[i][j] = -1;
			j--;
		}
		if(j<n-1)
		j++;
		if (i >= 0 && i < n - 1)
			i++;
	}
	return 0;
}


7 Sine之舞

在这里插入图片描述

#include<stdio.h>
/*这一题应该考察的是用递归的方式解决问题,但我搞不定这种,靠的就是观察公式规律,拆分部分打印*/
void An_output(int n){//打印式子An
	if(n==1)printf("sin(1)");
	else{
		printf("sin(1");
		int i;
		for(i=2;i<=n;i++){
			if(i%2==0)printf("+sin(%d",i);
			else printf("-sin(%d",i);
		}
		for(i=0;i<n;i++)printf(")");
	}
}
void Sn_output(int n){//已知An后,打印输出Sn
	if(n==1){
		An_output(1);
		printf("+1");
	}
	else{
		int i;
		for(i=0;i<n-1;i++)printf("(");
		for(i=1;i<=n-1;i++){
			An_output(i);
			printf("+%d)",n-i+1);
		}
		An_output(n);
		printf("+1");
	}
}
int main(){
	int n;
	scanf("%d",&n);
	Sn_output(n);
	return 0;
}

8 矩形面积交

在这里插入图片描述
在这里插入图片描述
思路:判断第二个矩形有没有点a在第一个矩形范围内(某个点a的横坐标大于第一个矩形横坐标较小的点小于横坐标较大的点,并且a的纵坐标同样满足要求,那么点a在第一个矩形范围内),若有,则求出相交范围的长和宽即可(长:第一个矩形横坐标的较大者减去a点的横坐标;宽:按照求长同样的方法求得)


#include<stdio.h>
#include<math.h>

void swap(double *a, double *b); 
double max(double a, double b);
double min(double a, double b);

int main() {
	double area = 0;// 相交的面积 
	double x11 = 0, y11 = 0, x12 = 0, y12 = 0;// 第一个矩形 
	double x21 = 0, y21 = 0, x22 = 0, y22 = 0;// 第二个矩形 
	double x1 = 0, y1 = 0, x2 = 0, y2 = 0;// 相交矩形的两个点 
	
	scanf("%lf%lf%lf%lf", &x11, &y11, &x12, &y12); 
	scanf("%lf%lf%lf%lf", &x21, &y21, &x22, &y22); 

	// 统一处理成给定的点一个在左下,一个在右上的方式 
	if (x11 > x12) 
		swap(&x11, &x12);
	if (y11 > y12) 
		swap(&y11, &y12);
	if (x21 > x22) 
		swap(&x21, &x22);
	if (y21 > y22) 
		swap(&y21, &y22);	
		
	// 将四种相交情况处理成一种,记录相交矩形的左下角和右上角的坐标
	x1 = max(x11, x21);
	x2 = min(x12, x22);
	y1 = max(y11, y21);
	y2 = min(y12, y22);
	
	if (x1 > x2 || y1 > y2)// 不相交
		area = 0;
	else {
		area = (x2 - x1) * (y2 - y1);
	}
	printf("%.2f", area);
		
	return 0;
}

// 交换两个数  
void swap(double *a, double *b) {
	double temp = *a;
	*a = *b;
	*b = temp; 
} 

double max(double a, double b) {
	return a > b ? a : b;
}

double min(double a, double b) {
	return a < b ? a : b;
}

9 矩阵乘法

在这里插入图片描述
在这里插入图片描述

10 分解质因数

在这里插入图片描述

#include <stdio.h>
#include<math.h>
 
void div(int n)
{
	int temp=n,i;
 
	for (i = 2; i <= sqrt(n); i++)
	{
		while (temp % i == 0 && temp != i)
		{
			temp = temp / i;
			printf("%d*",i);
		}
	}
 
	printf("%d\n",temp);
}
 
int main() {
	int a, b,i;
	while (scanf("%d %d", &a, &b) != EOF)
	{
		if (a >= 2 && b <= 10000 && a <= b)
		{
			for (i = a; i <= b; i++)
			{
				printf("%d=",i);
				div(i);
			}
		}
	}
 
	return 0;
}

11 字符串对比

在这里插入图片描述
思路:使用C++的tolower函数,将大写字母改为小写

#include <iostream>
#include <string.h>
 
using namespace std;
 
int main(){
    string a,b;
    cin>>a>>b;
    
    if(a.size()!=b.size()){
        cout<<"1";
    }
    else if(a==b){
        cout<<"2";
    }
    else{
        //把a,b中的每个字母转成小写
        for(int i=0;i<a.size();i++){
            a[i]=tolower(a[i]);
        }
        for(int i=0;i<b.size();i++){
            b[i]=tolower(b[i]);
        }
        if(a==b){
            cout<<"3";
        }
        else cout<<"4";
    }
    
   
    return 0;
}

12 时间转换

在这里插入图片描述

思路:先求出小时,再求分钟,最后求秒

#include<stdio.h>
int main(){
	int H,M,S,T;
	while(scanf("%d",&T)!=EOF){
		M=T/60;
		H=M/60;printf("%d:",H);
		M=M-H*60;printf("%d:",M);
		S=T-H*60*60-M*60;printf("%d",S);
	}
	return 0;
}

19 排队打水问题

在这里插入图片描述

#include <algorithm>
#include"stdio.h"
using namespace std;
int a[501]={0};
int v[501]={0};
int main()
{
	int n,r,sum=0;
	scanf("%d %d",&n,&r);
	int i;
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	sort(a,a+n);//小到大排序
	for(i=0;i<n;i++)
	{
		sort(v,v+r);//从小到大排列,
		sum+=v[0]+a[i];
		v[0]+=a[i];//自己的打水时间加上前面人的打水时间
	}
	printf("%d\n",sum);
	return 0;

}


21 分分钟的碎碎念

在这里插入图片描述

#include<iostream>
#include<algorithm>
using namespace std;
int from[1001];
int dp[1001];
int main () {
    int n, ans = 0;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> from[i];
    }
    for (int i = 1; i <= n; i++) {
        dp[i] = dp[from[i]] + 1;
        ans = max(dp[i], ans);
    }
    cout << ans;
    return 0;
}

22 现代诗如蚯蚓

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<stdio.h>
#include<string.h>


  int main()
  {
      int k=1,i;
      char a[10000];
      scanf("%s",a);
      int fog=0;
      for( i=1;i<strlen(a);i++)//每个串的长度依次为1,2....n
      {
          if(strlen(a)%i!=0)//如果不能划分为等长子串,则跳过
            continue;
          for( k=0;k<strlen(a);k++)
          {
              if(k+i<strlen(a))
                 if(a[k]!=a[k+i])
                    {
                       fog=1;
                       break;
                    }
          }
          if(fog==0)
            break;
          if(fog==1)
            fog=0;
      }
      printf("%d",strlen(a)/i);
      return 0;
  }


25 超级玛丽

在这里插入图片描述
思路
从 第 1 个位置,可以走一步,或者两步
从位置1到终点的解法数目,等于【从位置2到终点的解法数目】+【从位置3到终点的解法数目】
走之前判断下能不能走(是否有陷阱)

#include <iostream>

using namespace std;

#define maxlen 44
#define trap 114
#define safe 514

int n, m;
int road[44];

int cnt = 0;

void dfs(int x)
{
	if(x == n)
	{
		cnt += 1;
	}
	
	if(road[x+1] == safe)
	{
		dfs(x+1);
	}
	
	if(road[x+2] == safe)
	{
		dfs(x+2);
	}
}

int main()
{
	cin>>n>>m;
	
	for(int i=1; i<=n; i++)
	{
		road[i] = safe;
	}
	
	for(int i=1; i<=m; i++)
	{
		int t;
		cin>>t;
		road[t] = trap;
	}
	
	dfs(1);
	
	cout<<cnt<<endl;
	
	return 0;
}




26 聪明的美食家

在这里插入图片描述
思路:本题的意思是从开始吃,他的美味度必须一次比一次大,输出的是吃的爽最大的次数
本题思想可以用动态规划的思想去做,可以这么想,输入有n个美味度,在第i个位置的美味度可以表示为吃的爽的最大次数用dp[i]存储。最终输出最大次数即可

通过比较当前位置与前面数值的大小来判断

#include<stdio.h>
#define N 1002
int main()
{
    int n,i,j,max,len;
    int a[N],dp[N];
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&a[i]);
        dp[i]=1;
    }
    for(i=1;i<=n;i++){//第i个位置
        len=1;
        for(j=i-1;j>=1;j--){//
            if(a[i]>=a[j]){
                if(dp[i]+dp[j]>len){
                    len=dp[i]+dp[j];//这里dp[i]为1;dp[j]为第j位置的最大次数
                }
            }
        }
        dp[i]=len;//存储该位置的最大次数
        if(i==1){
            max=len;
        }
        if(max<len){
            max=len;
        }
    }
    printf("%d",max);
    return 0;
}



28 师座操作系统

在这里插入图片描述

#include <iostream>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

map<string,int>mp;
map<string,string>mmp;
int main(){
    string s,name,info;
    int type;
    while(cin>>s){
        if(s == "exit")
            break;
        else if(s == "create"){
            cin>>name>>type>>info;
            mp[name] = type;
            mmp[name] = info;
        }else if(s == "open"){
            cin>>name;
            while(mp[name] == 1){
                name = mmp[name];
            }
            cout<<mmp[name]<<endl;
        }
    }
    return 0;
}


29 洗牌

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
 
int cov(char ch) {//将字符转换为数字
    if (ch == 'K') return 13;
    if (ch == 'Q') return 12;
    if (ch == 'J') return 11;
    return ch - '0';
}
 
int main() {
    vector<int> Puke; char ch;
    while (cin >> ch) { //将字符存入puke
        if (ch == '0')//处理10
            Puke.pop_back(), Puke.push_back(10);
        else 
            Puke.push_back(cov(ch));
    }
    if (Puke.size() != 52) {//丢失牌输出-1
        cout << -1 << endl; exit(EXIT_SUCCESS);
    }
    vector<int> ans;
    while (!Puke.empty()) {
        int now = Puke.front(); //每次去头部元素
        Puke.erase(Puke.begin());//删除头部元素
        if (now >= ans.size())//若不足p张牌,将其放到最后
            ans.push_back(now);
        else
            ans.insert(ans.begin() + now, now);//插入到now后面
    }
    for (int pos = 0; pos < 52; pos++) {
        if (ans[pos] == 13) cout << 'K';
        else if (ans[pos] == 12) cout << 'Q';
        else if (ans[pos] == 11) cout << 'J';
        else if (ans[pos] == 10) cout << 10;
        else cout << ans[pos];
        cout << ' ';
    }
}

30 盾神与砝码称重

在这里插入图片描述
可恶,超时了
在这里插入图片描述

//思路:砝码分  天平左边,右边,或者不放  这三种情况。
#include<iostream>
using namespace std;
int n,m,num;
int arr[25];
bool dfs(int left,int right,int k){
	if(left == right) return true;
	if(k > n) return false;
	return dfs(left+arr[k],right,k+1) || dfs(left,right+arr[k],k+1) || dfs(left,right,k+1);
}
	
int main()
{
	cin>>n>>m;
	for(int i = 0;i < n;i ++){
		cin>>arr[i];
	}	
	while(m --){
		cin>>num;
		if(dfs(num,0,0)) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

32 网络警察

在这里插入图片描述
思路:将第一行的每个关键字存下来,然后对每个关键字sort排序。

将第二行待检查句子中的每个单词存下来,对每个单词sort排序,然后和上面的排序后的关键字依次判断是否相等,相等的话,再输出未排序的原关键字。

然后就是怎样实现将一行以空格分隔的字符串每个都提取出来。

然后新学了c++中的istringstream方法。

#include <bits/stdc++.h>
using namespace std;
int main() {
    string str1, str2;
    getline(cin, str1); //存储第一行的关键词
    getline(cin, str2); //存储第二行待检查的句子
    vector<string> s1, s2, s3;
    //s1存储关键字单词
    //s2存储排序后的关键字单词
    //s3存储排序后的待检查句子中的单词
    istringstream Str1(str1), Str2(str2); //绑定
    string temp;
    while (Str1 >> temp) {
        s1.push_back(temp);
        s2.push_back(temp);
    }
    while (Str2 >> temp) {
        s3.push_back(temp);
    }
    for (int i = 0; i < s3.size(); i++) {
    //将vector<string> s3中的每一个string元素s3[i]排序
        sort(s3[i].begin(), s3[i].end());
    }
int flag=0;
    for (int i = 0; i < s2.size(); i++) { //遍历s2中的每一个元素
        sort(s2[i].begin(), s2[i].end()); //将s2中的每一个元素排序
        for (int j = 0; j < s3.size(); j++) { //遍历s3
            if (s3[j] == s2[i]) { //排序之后的s3中的元素等于排序之后s2中的元素的话
                if(flag==0)
                {
                      flag=1;
                     cout << s1[i]; //输出s1中未排序的关键字单词
                }
                else
                  {
                    cout<<" "<<s1[i];
                  }
            }
        }
    }
    return 0;
}

34 我们的征途是星辰大海

在这里插入图片描述
在这里插入图片描述
思路:简单的模拟题,用x,y控制坐标

#include<stdio.h>
#include<string.h>
int T,N,Q;
char maze[100][100],quest[2020];
void operate(int x,int y)
{
    int len=strlen(quest);
    for(int i=0;i<len;++i)
    {
        if(quest[i]=='R')y++;
        else if(quest[i]=='L')y--;
        else if(quest[i]=='U')x--;
        else if(quest[i]=='D')x++;
        if(x>N || x<1 || y>N || y<1)
        {
            puts("I am out!");
            return;
        }
        else if(maze[x][y]=='#')
        {
            puts("I am dizzy!");
            return;
        }
        else if(maze[x][y]=='T')
        {
            puts("I get there!");
            return;
        }
    }
    puts("I have no idea!");
}
int main()
{
    scanf("%d ",&T);
    while(T--)
    {
        memset(maze,0,sizeof(maze));
        int x=0,y=0;//起始位置的坐标
        scanf("%d ",&N);
        for(int i=1;i<=N;++i)
        {
            for(int j=1;j<=N;++j)
            {
                scanf("%c",&maze[i][j]);
                if(maze[i][j]=='S'){x=i;y=j;}//起始点
            }
            getchar();
        }
        scanf("%d ",&Q);
        for(int i=1;i<=Q;++i)
        {
            gets(quest);
            operate(x,y);
        }
    }
    return 0;
}


35 快速幂

在这里插入图片描述

#include<stdio.h>
int main()//快速幂有规律
{
    long long a,b,ans;
    int p;
    scanf("%lld %lld %d",&a,&b,&p);
    ans=1;
    a%=p;
    while(b>0)
    {
        if(b&1)ans=ans*a%p;//奇数要多乘一次
        a=a*a%p;
        b>>=1;//b除2
    }
    printf("%d\n",ans);
    return 0;
}


39 最大乘积

在这里插入图片描述
思路:对输入的数字从小到大排序,对于负数,必须是成对相乘,若为正数,则从最后一个一个相乘

#include "stdio.h"
#include "string.h"
#include "math.h"

int main()
{
	int n,m,l,k,t,sum,min1;
	int a[100],b[100],c[100];



	while(scanf("%d",&n)!=EOF)
        {

         for(int i=0;i<n;i++)
         {
             sum=1;
             scanf("%d%d",&a[i],&b[i]);
             for(int j=0;j<a[i];j++)
                scanf("%d",&c[j]);

             for(int j=0;j<a[i];j++)
             {
                 min1=j;
                 for(int y=j+1;y<a[i];y++)
                    if(c[min1]>c[y])
                        min1=y;
                if(min1!=j)
                {
                     t=c[min1];
                     c[min1]=c[j];
                     c[j]=t;
                }

             }
             int p=0,q=a[i]-1,r=b[i];   //p从负数绝对值最大值开始,q从正数最大开始

             while(p<=a[i]-1&&q>=0&&r>0)
             {
                 if(c[p]*c[p+1]>c[q]*c[q-1]&&r>=2) //如果出现两个负数相乘大于两个正数相乘 
                 {
                     sum=sum*(c[p]*c[p+1]);
                     p+=2;
                     r-=2;
                 }
                 else
                 {
                     sum=sum*c[q]; //正数一个一个的来,负数必须成对
                     q--;
                     r--;
                 }

             }

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

         }

return 0;



        }




40 排列数

在这里插入图片描述
思路:需要用到全排列函数next_premutaion()

#include <algorithm>
#include <stdio.h>
using namespace std;

int num = 0;
int main ()
{
	int n;
	scanf("%d",&n);
	int i;
	int a[]={0,1,2,3,4,5,6,7,8,9};
	int b=10;
	do
	{
		num++;
		if(num == n)
		{
			for(i=0;i<10;i++)
				printf("%d",a[i]);	
		}
	}while(next_permutation(a,a+b));//对数组a的b个数进行全排列
	return 0;
}

43 最少操作数

在这里插入图片描述

/*
	T43 最少操作数 
	算法概述:逆向思维,题目中说要从a变换得到b,那也可以看成是从b变换得到a
	对每个步骤的每个数,若它是奇数,那么它肯定是由上一个数加1得到的;若它是
	偶数,由于要以最快的速度降到0,那么它肯定是由上一个数乘2得到的。这样就
	可以一步步的变成0,统计下操作次数就可以了 
*/ 

#include<stdio.h>
#define MAX_SIZE 55 

int main() {
	int res = 0;// 统计操作次数 
	int flag = 0;// 标记变量 
	int i = 0, n = 0;
	int B[MAX_SIZE] = {0};
	
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d", &B[i]);
	
	while (1) {
		flag = 0;
		for (i = 0; i < n; i++) {// 处理奇数 
			if (B[i] % 2 == 1) {
				res++; 
				B[i]--;
			} 
			
			if (B[i] != 0)
				flag = 1; 
		} 
		
		if (!flag)// 全为0,操作结束 
			break;
		
		for (i = 0; i < n; i++) // 处理偶数 
			B[i] /= 2;
		res++;
	}
	printf("%d\n", res);
	
	return 0;
} 


44 多项式输出

在这里插入图片描述

在这里插入图片描述

#include <iostream>
using namespace std;
int main() {
	int n,a[1000];
	cin>>n;
	for(int i=n;i>=0;i--){
		cin>>a[i];
		if(a[i]!=0){
			if(i!=0){
				if(i!=n&&a[i]>0) cout<<"+";
				if(a[i]==-1) cout<<"-";
				else if(a[i]!=1) cout<<a[i];
				cout<<"x";
				if(i!=1) cout<<"^"<<i;
			}else{
				if(a[i]>0) cout<<"+";
				cout<<a[i];
			}
		}
	} 
 return 0;
}

45 和最大子序列

在这里插入图片描述

#include<iostream>
using namespace std;
int max(int a,int b)
{
  return a>b?a:b;
}
void ON3(int test[],int arraysize)
{
   int thissum,maxsum=-INF;//初始化最大值为负无穷
   for(int index1=0; index1<arraysize; index1++)//枚举子序列的起点下标
    {
       for(int index2=index1; index2<arraysize; index2++)//枚举子序列的终点下标
       {
           thissum=0;
           for(int index3=index1; index3<=index2; index3++)//求[index1,index2]子序列的和
           {
                thissum=thissum+test[index3];
           }
           maxsum=max(maxsum,thissum);// 更新最大值
       }
    }
   cout<<"最大连续和为:"<<maxsum<<endl;
}

int main()
{
   int n;
    int a[100];
    cin>>n;
    int i;
    for(i=0;i<n;i++)
    {
       cin>>a[i];
    }
    int len=i;
    ON3(a,len);
   return 0;
}

52 k倍区间

在这里插入图片描述

思路:这道题的正确做法是使用前缀和取模,不过我看不懂,我使用的是枚举,超时了

#include <bits/stdc++.h>
using namespace std;
long long a[100000];
int main()
{
	int n,k;
	int sum=0,cnt=0;
	cin>>n>>k;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	for(int i=0;i<n;i++)
	{
		sum=0;
		for(int j=i;j<n;j++)
		{
			sum+=a[j];
			if(sum%k==0)
			{
				cnt++;
			}
		}
	}
	cout<<cnt;
	return 0;
}

59 核桃的数量

在这里插入图片描述

思路:找到三个数的最小公倍数,其范围在最大的数和三个数的乘积之间

#include<iostream>
using namespace std;
int main()
{
  int num;//每袋核桃数量
  int max=0;
  int a,b,c;
  cin>>a>>b>>c;
  if(a>b)
  {
    max=(a>c)?a:c;
  }
  else if(a<b)
  {
    max=(b>c)?b:c;
  }
  int i;
  for(i=max;i<=a*b*c;i++)
  {
    if(i%a==0&&i%b==0&&i%c==0)
    {
      num=i;
      break;
    }
  }
  cout<<num<<endl;
  return 0;
}

61 带分数

在这里插入图片描述
思路:题目要求n = a + b / c,可化为n * c = a * c + b,令a范围在[1,i],b=[i+1,j] c=[j+1,9](因为a,b,c数字为0-9)

// n = a + b / c
// n * c = a * c + b
#include<bits/stdc++.h>
using namespace std;
int num[20];
int fun(int l,int r)
{
    int res=0;
    for(int i=l;i<=r;i++)
    {
        res=res*10+num[i];
    }
    return res;
}
int main()
{
    int n,ans=0;
    cin>>n;
    for(int i=1;i<=9;i++) num[i]=i;
    do
    {
        for(int i=1;i<=9;i++)
        for(int j=i+1;j<=9;j++)
        {
            int a=fun(1,i);
            int b=fun(i+1,j);
            int c=fun(j+1,9);
            if(n*c==a*c+b) ans++;
        }
    }while(next_permutation(num+1,num+10));
    cout<<ans<<endl;
    return 0;
}

63 翻硬币

在这里插入图片描述
思路:遍历字符串,若当前字符不等于目标字符,令当前字符的下一个字符转变方向,计数+1,依次往后遍历

#include <cstdio>
#include <cstring>
 
using namespace std;
 
char a[1005],b[1005];
int len,i=0,ans=0;
 
int main() {
    scanf("%s%s",a,b);
    len=strlen(a);
    while(i<len) {
        if(a[i]!=b[i]) {
            a[i+1]=(a[i+1]=='*'?'o':'*');
            ++ans;
        }
        ++i;
    }
    printf("%d\n",ans);
}

64 连号区间数

在这里插入图片描述

#include<iostream>
using namespace std;

const int MAX=50010;
int arr[MAX];

int main()
{
	int n,max,min,ans=0;
	cin>>n;
	for(int i=0;i<n;i++) cin>>arr[i];
	for(int i=0;i<n;i++)
	{
		max=0,min=MAX;					//初始化最大值与最小值 
		for(int j=i;j<n;j++){
			max=arr[j]>max?arr[j]:max;	//检测最大值是否变化(并修改) 
			min=arr[j]<min?arr[j]:min;	//检测最小值是否变化(并修改) 
			if(max-min == j-i) ans++;	//max-min == j-i 则意味着是连号区间 
		}
	}
	cout<<ans<<endl;
	return 0;
}

68 回文数字

在这里插入图片描述

#include <stdio.h>
int main(void)
{
    int n, flag=1,t,i,num,sum;
    scanf("%d", &n);
    for(i=11011;i<=999999;i++)
    {
        t = i, num = 0, sum = 0;
        while(t>0)
        {
            num = num*10 + t%10;
            sum += t%10;
            t /= 10;
        }
        if(num==i && sum==n)
        {
            flag = 0;
            printf("%d\n", i);
        }
    }
    if(flag)printf("-1\n");
    return 0;
}

73 蚂蚁感冒

在这里插入图片描述

#include<stdio.h>
 int abss(int s)//取绝对值 
 { if(s<0)return -s;
    else return s;
 }
int  main()
{
  int qans=0,hans=0,n,i,gm,s;
  scanf("%d",&n); 
  scanf("%d",&gm);//gm 首个感冒蚂蚁 位值 
    for(i=1;i<n;i++)
     {
       scanf("%d",&s);
       if(abss(gm)<abss(s)&&s<0)hans++;//当在首个蚂蚁右侧并且反向 必感冒 
       if(abss(gm)>abss(s)&&s>0)qans++;//当在首个蚂蚁左侧并且正向 必感冒 
     }
  if(gm>0&&hans!=0||gm<0&&qans!=0)printf("%d",qans+hans+1);
   else printf("1");//当首个感冒蚂蚁方向为正时 在首个蚂蚁右侧并且反向 为 0 或  
return 0; //当首个感冒蚂蚁方向为负时 在首个蚂蚁左侧并且反向 为 0 则不会被感冒除首个感冒 
}

77 分糖果

在这里插入图片描述
思路:1、判断每个孩子的糖果数目是否相等,如果相等,则程序不执行
2、刚开始每个孩子要给出一半的糖果,由于初始糖果都是偶数,全体除以2
3、将要分出一半的糖果分给左边的小伙伴,即全体小朋友接收来自左边朋友的 一半糖果,注意,序号为最后一个小孩分配给第一个小孩时要借助变量分配
4、判断此时谁的糖果数是奇数,则老师分配给这个小孩

#include<stdio.h>
int main()
{  
 int a[100];
 int n,i,flag,temp,sum=0;
 scanf("%d",&n);
 for(i=0;i<n;i++)
  scanf("%d",&a[i]);
 while(1){                //判断条件
  for(i=0;i<n;i++)     //判断每个孩子的初始糖果数是否相等
  {
   if(a[0]!=a[i])   
   {
    flag=1;      //如果不相等,跳出此层循环
    break;
   }
   else
    flag=0;       
  }
  
  if(flag==0)  break;   //如果相等,则这个程序不执行
  
  for(i=0;i<n;i++)
  {
   a[i]=a[i]/2;      //刚开始每个孩子的糖果数都要分一半
  }  
   temp=a[n-1];           //将a[n-1]保存到temp变量中
  for(i=n-1;i>0;i--)//孩子顺时针排列
  {
   a[i]=a[i]+a[i-1];   //将每个孩子初始糖果的一半分给左边的孩子,注意,此时循环结束的最后一个式子是a[1]=a[1]+a[0]
                       //此时a[0]并没有拿到a[n-1]分来的糖果
  }
   
  a[0]=temp+a[0];        //此时将a[n-1]的一半糖果分到a[0]
  for(i=0;i<n;i++)
  {  
   if(a[i]%2==1)      //如果孩子的糖果数是奇数,则老师分配一个糖果,变成偶数个糖果
   {
    a[i]++;
       sum++;        //记录老师分配的糖果数
   }
  }
 }
 printf("%d\n",sum);      //输出
 return 0; 
}

81 日期问题

思路
将十二个月定义于一个数组中,用于后期判断每个月的天数是否符合。
定义三个函数,分别是:判断是否闰年函数;输出每个月天数函数;打印输出函数。在打印输出函数中判断日期是否符合实际情况,不符合返回,符合打印。
在这里插入图片描述
在这里插入图片描述

#include<iostream>
using namespace std;
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int year1=0,month1=0,day1=0;
bool is_leap(int year)  //是否闰年
{
    return year%400==0||year%4==0&&year%100!=0;
}
int get_days(int year,int month) //月份天数
{
    if(month==2) return 28+is_leap(year);
    return months[month];
}
void jupe(int year,int month,int day)
{
    if(year1==year&&month1==month&&day1==day) return;//排除出现同一天多次
    year1=year,month1=month,day1=day;//保留上一次数据
    if(month<1||month>12) return;  //月是否符合实际
    if(day<1||day>get_days(year,month)) return;//日是否符合月份天数
    if(year>=60&&year<=99)  //年的判断
    {
        year=year+1900;
    }
    else
    {
        year=year+2000;
    }
    printf("%d-%.2d-%.2d\n",year,month,day);
}
int main()
{
    int a,b,c;
    scanf("%d/%d/%d",&a,&b,&c);
    jupe(a,b,c);  //年月日
    jupe(c,a,b);   //月日年
    jupe(c,b,a);   //日月年
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值