东华大学研究生计算机复试进阶题
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;
}