C++编程

计数排序

在这里插入图片描述

前缀和

在这里插入图片描述

统计字符

在这里插入图片描述

#include <iostream>
#include <cstdio>
using namespace std;
int cnt[26];
int main(){
	freopen("count.in","r",stdin);
	freopen("count.out","w",stdout);
	string s;
	cin>>s;
	for(int i=0;i<s.size()-1;i++){
		if('A'<=s[i]&&s[i]<='Z'){
			cnt[s[i]-'A']++;
		}else{
			cnt[s[i]-'a']++;
		}
	} 
	int max=0,index;
	for(int i=0;i<26;i++){
		if(cnt[i]>max){
			max=cnt[i];
			index=i;
		}
	}
	cout<<max<<" "<<(char)(index+'A');
	return 0;
}

越野比赛

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

#include<iostream>
#include<cstdio>
using namespace std;
long long d[100005],sum[100005];
int main(){
	freopen("hike.in","r",stdin);
	freopen("hike.out","w",stdout);
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=1;i<n;i++){
		scanf("%lld",&d[i]);
	}
	
	for(int i=1;i<n;i++){
		sum[i]=sum[i-1]+d[i];
	}
	
	int a,b;
	for(int i=0;i<k;i++){
		scanf("%d%d",&a,&b);
		printf("%lld ",sum[b-1]-sum[a-1]);
	}
	return 0;
} 

多项式

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

#include<iostream>
#include<cstdio>
using namespace std;
int in_num[4],in_index[4],out_num[4],out_index[4];
int main(){
	freopen("mul.in","r",stdin);
	freopen("mul.out","w",stdout);
	int a,b;
	for(int i=0;i<4;i++){
		cin>>a>>b;
		in_num[i]=a;
		in_index[i]=b;
	}
	out_num[0]=in_num[0]*in_num[2];
	out_num[1]=in_num[0]*in_num[3];
	out_num[2]=in_num[1]*in_num[2];
	out_num[3]=in_num[1]*in_num[3];
	out_index[0]=in_index[0]+in_index[2];
	out_index[1]=in_index[0]+in_index[3];
	out_index[2]=in_index[1]+in_index[2];
	out_index[3]=in_index[1]+in_index[3];
	
	for(int i=0;i<4;i++){
		for(int j=i+1;j<4;j++){
			if(out_index[i]==out_index[j]){
				out_num[i]=out_num[i]+out_num[j];
				out_index[j]=0;
				out_num[j]=0;
			}
		}
	} 
	int  temp,temps;
	for(int i=0;i<4;i++){
		for(int j=i+1;j<4;j++){
			if(out_index[j]>out_index[i]){
				temp=out_index[i];
				out_index[i]=out_index[j];
				out_index[j]=temp;
				temps=out_num[i];
				out_num[i]=out_num[j];
				out_num[j]=temps;
			}
		}
	} 
	
	for(int i=0;i<4;i++){
		if(out_num[i]!=0){
			cout<<out_num[i]<<" "<<out_index[i]<<endl;
		}
	} 
	return 0;
} 

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多 44 个正整数的平方和。如果把 00 包括进去,就正好可以表示为 44 个数的平方和。
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
    freopen("square.in","r",stdin);
    freopen("square.out","w",stdout);
    int N;
    cin>>N;
    for(int i=0;i<N;i++){
    	if(i*i>N)break;
        for(int j=0;j<N;j++){
        	if(j*j>N)break;
            for(int k=0;k<N;k++){
            	if(k*k>N)break;
            	double m=sqrt(N-i*i-j*j-k*k); 
                if(int(m)==m){
                    cout<<i<<" "<<j<<" "<<k<<" "<<m<<endl;
                    return 0;
                }
            }
        }
    }
    return 0;
} 

在这里插入图片描述

装饰效果

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

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    int n,a[1005]={0};
    int max1=0,sum=0;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            sum+=a[j];
            if(sum>max1){
            	max1=sum;
			}
        }  
		sum=0;
    }
    cout<<max1;
    return 0;
}

奖券数目

有些人很迷信数字,比如认为带 4 的数不吉利。某抽奖活动的奖券号码是 55 位数 (10000-99999)(1000099999),要求其中不要出现带“4”的号码,主办方想让你计算一下,如果发行号码 n 到 m 之间的奖券,在任何两张奖券都不重复的情况下,可以发行多少张?
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    freopen("ticket.in","r",stdin);
    freopen("ticket.out","w",stdout);
    int n,m,cnt=0;
    cin>>n>>m;
    for(int i=n;i<=m;i++){
        int a=i/10000;
        int b=i/1000%10;
        int c=i/100%10;
        int d=i/10%10;
        int e=i%10;
        if(a!=4&&b!=4&&c!=4&&d!=4&&e!=4)
            cnt++;
    }
        cout<<cnt;
    return 0;
}

在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
    freopen("len.in","r",stdin);
    freopen("len.out","w",stdout);
    int n,L[105];
    int min=10001;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>L[i];
    }
    for(int i=1;i<n;i++){//定位置 
        for(int j=i+1;j<=n;j++){//移动遍历 
            int cha=abs(L[j]-L[i]);
            if(cha<min){
                min=cha;
            }
        }    
    }
    cout<<min;
    return 0;
}

北极圈远征

在征服南极之后,Davor 开始了一项新的挑战。下一步是在西伯利亚、格林兰、挪威的北极圈远征。需要一共筹集 n 元钱。他打算在每个星期一筹集 x 元,星期二筹集 x+k  x+2k 元,……,星期日筹集 x+6k 元,并在 52 个星期内筹集完。其中 x,k 为正整数,并且满足 1<x<  100  1≤x≤100。

现在请你帮忙计算 x,k 为多少时,能刚好筹集 n元。
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    freopen("money.in","r",stdin);
    freopen("money.out","w",stdout);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
         for(int j=1;j<n;j++){
             int sum=52*(21*i+7*j);
             if(sum==n&&1<=j&&j<=100){
                 cout<<j<<endl<<i;
                 return 0;
             }
         }  
    }
    return 0;
}

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

#include <iostream>
#include <fstream>

using namespace std;

const int N  = 100;

int matrix[N + 1][N + 1], rowsum[N + 1][N + 1];
int m, n, i, j, first, last, area, ans;

int main()
{
	freopen("submatrix.in","r",stdin);
    freopen("submatrix.out","w",stdout);
	cin >> m >> n;
	
	for (i = 1; i <= m; i++)
		for (j = 1; j <= n; j++)
			cin >> matrix[i][j];
	
	ans = matrix[1][1];                          // 左上角第一个点 
	for (i = 1; i <= m; i++) rowsum[i][0] = 0;   //  原题这个地方有换行,造成阅读诱导 
	
	for (i = 1; i <= m; i++)
		for (j = 1; j <= n; j++)
			rowsum[i][j] = rowsum[i][j - 1] + matrix[i][j]; //每一行做一个前缀和
	
	for (first = 1; first <= n; first++)	       //n列,从第一列开始 
		for (last = first; last <= n; last++)  //先是列的维度 
		{
			area = 0;
			for (i = 1; i <= m; i++)      //再是行的维度,m行 						
			{
				area += rowsum[i][last] - rowsum[i][first - 1];   
				                      //ans打擂台,更新 
                                if (area > ans) ans = area;
				                     //上半部分的子矩阵和,如果是负数,清零,重头再来 	
				if (area < 0) area = 0; 					
			}
		} 
	
	cout << ans << endl;	

	return 0;
}

奶酪工厂

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

#include<bits/stdc++.h>
using namespace std;
int main(){
    freopen("yogurt.in", "r", stdin);
    freopen("yogurt.out", "w", stdout);
    int n, s;
    //n个星期,每周需要s个便士保存
    cin >> n >> s;
    long long ans = 0;//成本 //long long 为LL都行
    int now = 1e9;
    for(int i = 1; i <= n; i++){
        //生产一个单位需要c便士
        //需要交付y个单位
        int c, y;
        cin >> c >> y;
        now = min(now + s, c);	//比较成本
        ans += (long long) y * now;
    }
    cout << ans << endl;
    return 0;
}

节约用电

学校里有一条超长的走廊,可以看成是一条直线。走廊里一共有 n盏电灯,每盏电灯的位置为 为了响应国家的号召节约用电,校长决定关掉几盏电灯,仅维持走廊的基本光照。具体规则是,如果某盏灯的左右两盏亮着的灯距离不超过 m,就可以把这盏灯关闭。其中头尾两盏灯不允许关闭。

现在请你计算最多能关掉多少盏灯。

在这里插入图片描述

排序后贪心关灯,需要保存上一个没关的灯的位置,如果下一个位置的灯和上一个没关位置的灯距离不超过 m,当前位置的灯就可以关了。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100005];
int main(){
    freopen("light.in","r",stdin);
    freopen("light.out","w",stdout);
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    sort(a,a+n);//要贪心先排序
    int ans=0;//记录关几盏灯(最多)
    int last=a[0];
    for(int i=1;i<n-1;i++){
        if(a[i+1]-last<=m){
            ans++;
        }else{
            last=a[i];
        }
    }
    cout<<ans<<endl;
    return 0;
}

在这里插入图片描述

蘑菇森林

蒜头君来到蘑菇森林,这里有 nn 只僵尸蘑菇,每只僵尸蘑菇的闪避值为 x_ix 
i
​	
 ,血量为 y_iy 
i
​	
 。只有蒜头君的命中值大于等于怪物的闪避值,才能对怪物造成伤害。蒜头君一共有 mm 点能量值,他每次攻击会消耗一点能量,然后造成一点伤害(单体攻击,某个怪物血量减少 11)。

现在已知蒜头君的基础命中值为 hh,身上装备增加的命中值为 bb。现在蒜头君他想知道一共能杀死多少个僵尸蘑菇。

在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int blood[5005];
int main(){
    freopen("mushroom.in","r",stdin);
    freopen("mushroom.out","w",stdout);
    int n,m,h,b,ans=0;//定义变量//ans为最后杀死僵尸的数量
    cin>>n>>m>>h>>b;
    h+=b;
    int cnt=0;
    for(int i=1;i<=n;i++){
        int x,y;//能边输入一边处理则没必要用数组,可用临时变量处理
        cin>>x>>y;
        if(x<=h){
            blood[cnt++]=y;//或者blood[cnt],cnt++
        }
    }
    sort(blood,blood+cnt);
    for(int i=0;i<cnt;i++){//循环扫描
        if(m>=blood[i]){
            ans++;
            m-=blood[i];
        }
    }
    cout<<ans<<endl;
    return 0;
}

在这里插入图片描述

找球数

游戏规则为:在一堆球中,每个球上都有一个整数编号 i(0 \le i \le 10^9)i(0≤i≤10 
9
 ),编号可重复,现在说一个随机整数 k(0 \le k \le 10^9 + 100)k(0≤k≤10 
9
 +100),判断编号为 kk 的球是否在这堆球中(存在为"YES",否则为"NO"),先答出者为胜。现在有一个人想玩玩这个游戏,但他又很懒。他希望你能帮助他取得胜利。

本题输入输出量较大,请使用scanf/printf。

在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
    freopen("ball.in","r",stdin);
    freopen("ball.out","w",stdout);
    int m,n;
    //!!!!数组的定义要注意!!!! 
    scanf("%d %d",&m,&n);
    int M[m+1],N[n+1];
    for(int i=1;i<=m;i++){
        scanf("%d",&M[i]);
    }
    sort(M,M+m+1);
    for(int j=1;j<=n;j++){
        scanf("%d",&N[j]);
        if(binary_search(M,M+m+1,N[j])){
            cout<<"YES"<<'\n';
        }
		else{
            cout<<"NO"<<'\n';
        }   
    }
    //sort(N,N+n+1);排序捣乱顺序了 
    return 0;
} 

开花

蒜头君所在的学校又迎来了一年一度的奖励小红花活动,有 n名学生被评为文学优秀奖,m名学生被评为体育优秀奖。现已知两个奖项获奖同学的编号,每个同学都有唯一的编号。只有同时被评为文学优秀奖和体育优秀奖的学生才能获得小红花,蒜头君想知道获得小红花的学生的名单,请你帮他统计一下。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
    freopen("flower.in","r",stdin);
    freopen("flower.out","w",stdout);
    int n,m;
    cin>>n>>m;
    int num_n[n+1],num_m[m+1];
    for(int i=1;i<=n;i++){
        cin>>num_n[i];
    }
    for(int j=1;j<=m;j++){
        cin>>num_m[j];
    }
    sort(num_m,num_m+m+1);
    for(int i=1;i<=n;i++){
        if(binary_search(num_m,num_m+m+1,num_n[i]))
            cout<<num_n[i]<<" ";
    }
    return 0;
}

烦恼的高考志愿

计算机竞赛小组的蒜头君终于结束了万恶的高考,然而作为班长的他还不能闲下来,班主任给了他一个艰巨的任务:帮同学找出最合理的大学填报方案。可是蒜头君太忙了,于是他想到了同为计算机竞赛小组的你,请你帮他完成这个艰巨的任务。

根据 nn 位学生的估分情况,分别给每位学生推荐一所学校,要求学校的预计分数线和学生的估分相差最小(可高可低,毕竟是估分嘛),这个最小值为不满意度。求所有学生不满意度和的最小值。

#include<bits/stdc++.h>
using namespace std;
long long p1,p2,d1,d2,ans,x,num[1100000],n,m;
int main(){
	freopen("exam.in","r",stdin);
	freopen("exam.out","w",stdout);
	ios_base::sync_with_stdio(false);
	cin.tie(0);
    cin>>m>>n;
    for(int i=0;i<m;i++)cin>>num[i];
    sort(num,num+m);
    while(n--){
        cin>>x;
        p1=lower_bound(num,num+m,x)-num;p2=p1-1;d1=d2=20000000;
        if(p1!=m)d1=num[p1]-x;
        if(p2!=-1)d2=x-num[p2];
        ans+=min(d1,d2);
    }
    cout<<ans<<endl;
    return 0;
}

两数之和

蒜头君在玩 “两数之和” 游戏,一共 nn 局。每一局中他会得到 nn 个整数,如果他能从其中选出两个数字,使得它们的和为 kk,本局就算胜利,积一分并进行下一局。请问 nn 局比赛结束后,他的积分是多少?

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[1005];
int main() {
    freopen("sum.in", "r", stdin);
    freopen("sum.out", "w", stdout);
    int n, k, cnt = 0;
    cin >> n >> k;
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++){
            cin>>a[j];
        }
        sort(a, a + n);
        for(int j = 0; j < n; j++){
            if (binary_search(a + j + 1, a + n, k - a[j])) {
                cnt++;
                break;
            }
        }
    }
    cout << cnt << endl;
    return 0;
}

数列选作

在这里插入图片描述

#include <iostream>
#include <cstdio>
long long a[100005];
int num[100005];
using namespace std;
int main() {
    freopen("array.in", "r", stdin);
    freopen("array.out", "w", stdout);
    int n, q;
    long long k;
    scanf("%d%d", &n, &q);
    for(int i = 0; i < n; i++) {
        scanf("%lld%d", &a[i], &num[i]);
    }
    for(int i = 1; i < n; i++){
        a[i] += a[i - 1];
    }
    for(int i = 1; i <= q; i++){
        scanf("%lld", &k);
        printf("%d\n", num[lower_bound(a, a+n, k)-a]);
    }
    return 0;
}

山德士上校

哈兰·山德士上校,是肯德基品牌的创始人。发明了著名的“肯德基炸鸡”,开创了“肯德基快餐连锁”业务。肯德基是世界最大的炸鸡快餐连锁企业,在世界各地拥有超过 1500015000 家的餐厅,以山德士形象设计的肯德基标志,已成为世界上最出色、最易识别的品牌之一。

山德士上校年轻的时候去养鸡场买鸡:公鸡五美元一只,母鸡三美元一只,小鸡三只一美元。

现在山德士上校打算恰好用 nn 美元买 nn 只鸡,有多少种方案可以实现。

在这里插入图片描述

#include<iostream>
#include<cstdio>
using namespace std;
int ans;
int main(){
    freopen("kfc.in","r",stdin);
    freopen("kfc.out","w",stdout);
    int n;
    cin>>n;
    for(int i=0;i<=n;i++){
        int x=i;
        int y=(n-7*x)/4;
        if(x*5+y*3+(n-x-y)/3==n&&x>=0&&y>=0&&n-x-y>=0){
            ans++;
        }
    }
    if(ans==0){
        cout<<"No Answer.";
    }else{
        cout<<ans;
    }
    return 0;
}

相互认识

在蒜国,有 nn 户渔民住在海岸线上,整齐的排列成一条直线。每个渔民的房子我们用一个坐标 p_ip i​
来表示,每个渔民的活动半径为 dd。也就是说两个距离小于等于 dd 的房子,这两户渔民相互认识。
那么在蒜国,有多少对渔民相互认识?

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100005];
int main(){
  freopen("friend.in","r",stdin);
  freopen("friend.out","w",stdout);
    int n,d;
    cin>>n>>d;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    sort(a,a+n);
    long long ans=0;
    int pos=1;
    for(int i=0;i<n;i++){
        while(pos<n && a[pos]-a[i]<=d){//why时间复杂度为nlogn
            pos++;
        }
        ans += pos - i - 1;
    }
    cout<<ans<<endl;
    return 0;
}

蒜头君在上电脑课的时候,写了一个游戏。

游戏的内容是:在一个 n\times nn×n 的矩阵里,有若干个敌人。你可以选择一个 没有敌人 的位置放置激光炮,激光炮会朝东南西北四个方向发射激光,具有穿透性能消灭射线上的所有敌人。

现在蒜头君想考考你,把激光炮放置在哪个位置上消灭的敌人数量最多

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){
    freopen("laser.in","r",stdin);
    freopen("laser.out","w",stdout);
    int n;
    cin>>n;
    int num[n][n],row[n]={0},col[n]={0};//行row,列column的和
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>num[i][j];
            row[i]+=num[i][j];//行和
            col[j]+=num[i][j];//列和
        }
    }
    int ans=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(num[i][j]==0){
                ans=max(ans,row[i]+col[j]);
            }
        }
    }
    cout<<ans;
    return 0;
}

学姐点名

学姐辛辛苦苦准备了一次讲座,然后发现有一个学弟没有来,然后学姐非常生气想把那个学弟找出来。

讲座总共有 nn 个学弟参加,学弟们的学号分别为 1\sim n1∼n。学姐登记了所有到位的学弟的学号。作为一位非常仰慕她的小学妹,你希望能够帮她写一段代码找出来找到那个学弟。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){
    freopen("call.in","r",stdin);
    freopen("call.out","w",stdout);
    int n;
    cin>>n;
    int number[n];
    int cnt[n+1]={0};
    for(int i=1;i<n;i++){
        cin>>number[i];
        cnt[number[i]]++;
    }
    for(int i=1;i<=n;i++){
        if(cnt[i]==0)
            cout<<i;
    }
    return 0;
}

非常男女

近来,蒜头君致力于研究班上同学的配对问题(别想太多,仅是舞伴),通过各种推理和实验,他掌握了大量的实战经验。例如,据他观察,身高相近的人似乎比较合得来。

万圣节来临之际,蒜头君准备在学校策划一次大型的“非常男女”配对活动。对于这次活动的参与者,蒜头君有自己独特的选择方式。他希望能选择男女人数相等且身高都很接近的一些人。这种选择方式实现起来很简单。他让学校的所有人按照身高排成一排,然后从中选出连续的若干个人,使得这些人中男女人数相等。为了使活动更热闹,蒜头君当然希望他能选出的人越多越好。请编写程序告诉他,他最多可以选出多少人来。

#include<iostream>
#include<cstdio> 
#include<memory.h>
#include<vector>
using namespace std;

int main(){
	freopen("pair.in","r",stdin);
    freopen("pair.out","w",stdout);
	int a[100001];
	int Map[200001],sum[200001];
	int n,i,ans;
	cin >> n;
	for(i=1;i<=n;i++){
		cin >> a[i];
		if(a[i]==0) a[i]=-1;
		sum[i]=sum[i-1]+a[i];
	}
	
	for(i=1;i<=n;i++){
		//因为sum表示从1-n的前缀和,所以如果等于0;那么表示从1开始到目前这个数,
		//1和-1的个数是一样的,所以ans取max 
		if(sum[i]==0){
			ans=max(ans,i);
			continue;
		}
		//  Map[j]  记录j这个前缀和出现的最早位置
		//如果前缀和出现过,更新ans值。 
		if(Map[sum[i]+n]  && ans<i-Map[sum[i]+n])
			ans=i-Map[sum[i]+n];
		//如果这个和没有出现过,就记录当前第一次出现的位置 
		if(Map[sum[i]+n]==0) Map[sum[i]+n]=i;
	}
	cout<<ans<<endl;
	return 0;
}

逛画展

博览馆正在展出由世上最佳的 MM 位大师所画的图画。蒜头君想到博览馆去看这几位大师的作品,可是那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字 aa 和 bb,代表他要看展览中的第 aa 幅至第 bb 幅画(包含 aa 和 bb)之间的所有图画,而门票的价钱就是一张画一元。

为了看到更多大师的画,蒜头君希望入场后可以看到所有大师的图画(至少各一张),可是他又想节省金钱。作为蒜头君的朋友,他请你写一个程序决定他购买门票时的 aa 值和 bb 值。

#include<cstdio>
#include<algorithm>
#include<cstring> 
using namespace std;
 
int n,m,a,b;
int pic[1000090],cnt[1000090];
bool binfind(int x) {    
    int tmp=0;
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=x;i++)
    {
    if(!cnt[pic[i]]) tmp++;
    cnt[pic[i]]++;
    }
     if(tmp==m)
     {
         a=1,b=x;
         return 1;
     }
     int l=2,r=x+1;
     for(int i=l;r<=n;l++,r++)
     {
         cnt[pic[l-1]]--;
         if(!cnt[pic[l-1]]) tmp--;
         cnt[pic[r]]++;
         if(cnt[pic[r]]==1) tmp++;
         if(tmp==m)
         {
             a=l,b=r;
             return 1;
         }
     }
     return 0;
 }
 
int main()
{
    freopen("art.in","r",stdin);
    freopen("art.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&pic[i]);
    a=1,b=n;
    int l=1,r=n;
    while(l<r) {
         int mid=(l+r)/2;
         if(binfind(mid)) r=mid;
         else l=mid+1;
     }
     printf("%d %d",a,b);
     return 0;
 }

重力反转

物理课上小蒜太无聊了(物理对他来说太简单),于是他就造了一个玩具盒来打发时间。这个盒子非常神奇,你甚至可以去改变盒子中重力的方向。
盒子中有许多玩具立方体,总共 nn 列,每一列有 a_ia
i​ 个立方体,开始的时候重力的方向是竖直向下的,当小蒜改变了盒子中重力的方向之后,所有的立方体都开始向右边移动,下图分别表示初始每个立方体的状态和改变重力之后每个立方体的状态,橙色标记的方块表示位置发生过改变的立方体。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main ()
{
	freopen("gravity.in","r",stdin);
	freopen("gravity.out","w",stdout); 
    int n;
    cin>>n;
    int a[1005];
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    for(int i=0;i<n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
    return 0;
}

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

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int A[1005];
int main(){
    freopen("greedy.in","r",stdin);
    freopen("greedy.out","w",stdout);
    int n,v;
    cin>>n>>v;
    for(int i=1;i<=n;i++){
        cin>>A[i];
    }
    sort(A+1,A+n+1);
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=A[i];
        if(sum>v){
            cout<<i-1;
            break;
        }else{
           continue; 
        }
    }
    return 0;
}

ACM大赛

在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct Team{
    string name;
    int score;
    int time;
};
Team T[1005];
bool cmp(Team x,Team y){
   if(x.score>y.score){
       return 1;
   }
   else if(x.score==y.score)
   {
       if(x.time<y.time){
           return 1;
       }
       else if(x.time==y.time){
           if(x.name<y.name){
               return 1;
           }else{
               return 0;
           }
       }
       else return 0;
   }else{
       return 0;
   }
}
int main(){
    freopen("acm.in","r",stdin);
    freopen("acm.out","w",stdout);
    int n;
    cin>>n;//队伍的个数
    for(int i=0;i<n;i++){
        cin>>T[i].name>>T[i].score>>T[i].time;
    }
    sort(T,T+n,cmp);//struct sort
    for(int i=0;i<n;i++){
        cout<<T[i].name<<endl;
    }
    return 0;
}

表演

在这里插入图片描述

#include <algorithm>
#include <iostream>
using namespace std;
struct s{
	int val;
	int index;
}a[2005];
int main() {
    freopen("stable.in","r",stdin);
    freopen("stable.out","w",stdout);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i].val;
        a[i].index=i;
    }
    for(int i=1;i<=n;i++){
        bool swapped=false;
        for(int j=1;j<=n-i;j++){
            if(a[j].val<a[j+1].val){
                swap(a[j],a[j+1]);
                swapped=true;
            }
        }
        if(!swapped){
            break;
        }
    }
    for (int i = 1; i <= n; i++) {
        cout << a[i].val << " "<< a[i].index << " ";
    }
    return 0;
}

整数排序

在这里插入图片描述

#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct bigInt {
	int d[1005];
	int size;
	void init() {//初始化
		for (int i = 0; i < 1005; i++) {
			d[i] = 0;
		}
		size = 0;//目前还没有任何一个单位被使用
	}
	void set(char str[]) {//提取字符串
		init();
		int len = strlen(str);
		for (int i = len - 1; i >= 0; i--) {
			d[size++] = str[i] - '0';
		}
	}
	void output() {//输出函数
		for (int i = size - 1; i >= 0; i--) {
			printf("%d", d[i]);
		}
		if (size == 0) printf("0");
		printf("\n");
	}
}list[101];

bool cmp(bigInt a, bigInt b) {
	for (int i = 1005 - 1; i >= 0; i--) {
		if (a.d[i] < b.d[i]) return true;
		else if (a.d[i] > b.d[i]) return false;
	}
	return false;
}

int main() {
    freopen("sort.in","r",stdin);
    freopen("sort.out","w",stdout);
	int n;
	char str[1002];
	while (scanf("%d", &n) != EOF) {
		for (int i = 1; i <= n; i++) {
			scanf("%s", str);
			list[i].set(str);
		}
		sort(list + 1, list + 1 + n, cmp);
		for (int i = 1; i <= n; i++) {
			list[i].output();
		}
	}
	return 0;
}

大加数法

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
struct hugeint{
	int num[1005]={0};
	int len=0;
}; 
hugeint strtoint(string s){
	hugeint ans;
	for(int i=s.size()-1;i>=0;i--){
		ans.num[++ans.len]=s[i]-'0';
	}
	return ans;	
}
void printint(hugeint n){
	for(int i=n.len;i>=1;i--){
		cout<<n.num[i];
	}
	cout<<endl;
} 
//高精度+高精度 
hugeint add(hugeint a,hugeint b){
	hugeint ans;
	ans.len=max(a.len,b.len);
	for(int i=1;i<=ans.len;i++){
		ans.num[i]+=a.num[i]+b.num[i];
		ans.num[i+1]=ans.num[i]/10;
		ans.num[i]%=10;
	} 
	if(ans.num[ans.len+1]>0){
		ans.len++;
	} 
	return ans;
} 
int main(){
    freopen("bigadd.in","r",stdin);
    freopen("bigadd.out","w",stdout);
	string a,b="2018";
	cin>>a;
	hugeint n1=strtoint(a);
	hugeint n2=strtoint(b); 
	printint(add(n1,n2));
	return 0;
} 

A+B+C
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
struct hugeint{
	int num[1005]={0};
	int len=0;
}; 
hugeint strtoint(string s){
	hugeint ans;
	for(int i=s.size()-1;i>=0;i--){
		ans.num[++ans.len]=s[i]-'0';
	}
	return ans;	
}
void printint(hugeint n){
	for(int i=n.len;i>=1;i--){
		cout<<n.num[i];
	}
	cout<<endl;
} 
//高精度+高精度 
hugeint add(hugeint a,hugeint b){
	hugeint ans;
	ans.len=max(a.len,b.len);
	for(int i=1;i<=ans.len;i++){
		ans.num[i]+=a.num[i]+b.num[i];
		ans.num[i+1]=ans.num[i]/10;
		ans.num[i]%=10;
	} 
	if(ans.num[ans.len+1]>0){
		ans.len++;
	} 
	return ans;
} 
int main(){
    freopen("abc.in","r",stdin);
    freopen("abc.out","w",stdout);
	string a,b,c;
	cin>>a>>b>>c;
	hugeint n1=strtoint(a);
	hugeint n2=strtoint(b); 
    hugeint n3=strtoint(c); 
	printint(add(add(n1,n2),n3));
	return 0;
} 

大数减法

#include<iostream>
#include<cstdio>
using namespace std;

int main(){
    freopen("subtraction.in","r",stdin);
    freopen("subtraction.out","w",stdout);
    int a[10005]={0},b[10005]={0},c[10005]={0},aLen,bLen,maxLen;
    string as, bs;
    
    //输入两个大整数 
    cin>>as>>bs;
    
    //获取大整数的长度 
    aLen=as.length();
    bLen=bs.length();

    //大整数逆序存入a[]、b[] 
    for(int i=0;i<aLen;i++){
        a[i]=as[aLen-i-1]-'0';
    }
    
    for(int i=0;i<bLen;i++){
        b[i]=bs[bLen-i-1]-'0';
    }
    
    //去除大整数的前导0
    while(a[aLen-1]==0 && aLen>1){
        aLen--;
    }
    
    while(b[bLen-1]==0 && bLen>1){
        bLen--;
    }
    
    maxLen=max(aLen,bLen);
    
    //若a<b,输出一个负号,并交换a[]和b[],确保a[]存放较大数 
    if(aLen<bLen){
        cout<<'-';
        swap(a,b);
        swap(aLen,bLen);
    }
    
    if(aLen==bLen){
        for(int i=aLen-1,j=bLen-1;i>=0;i--){
            if(a[i]==b[i]){
                continue;
            }else if(a[i]>b[i]){
                break;
            }else{
                cout<<'-';
                swap(a,b);
                swap(aLen,bLen);
                break;
            }
        }
    }
    
    //计算a-b
    for(int i=0;i<maxLen;i++){
        if(a[i]<b[i]){
            a[i]+=10;
            a[i+1]--;
        }
        c[i]=a[i]-b[i];
    }
    
    //去除结果中的前导0
    while(c[maxLen-1]==0 && maxLen>1){
        maxLen--;
    }
    
    //输出结果 
    for(int i=maxLen-1;i>=0;i--){
        cout<<c[i];
    }
    cout<<endl;
    
    return 0;
}

 

稀疏图判断

在这里插入图片描述

#include <iostream>
#include<cstdio>

const int maxn=105;
int G[maxn][maxn];
using namespace std;
int main(){
	freopen("sparse.in","r",stdin);
	freopen("sparse.out","w",stdout);
    int n;
    cin>>n;
    int cnt=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>G[i][j];
            if(i!=j&&G[i][j]==1){
                cnt++;
            }
        }
    }
    if(cnt<=10*n){
        cout<<"Yes";
    }else{
        cout<<"No";
    }
	return 0;
}

在这里插入图片描述

图论入门

#include <iostream>
#include <cstdio>
using namespace std;
 
int out(int** pp, int n, int m) {
	int num = 0;
	for (int i = 0; i < n; ++i) {
		if (pp[m][i] != 0)
			++num;
	}
	return num;
}
 
int in(int** pp, int n, int m) {
	int num = 0;
	for (int i = 0; i < n; ++i) {
		if (pp[i][m] != 0)
			++num;
	}
	return num;
}
 
int num(int** pp, int n) {
	int num = 0;
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < n; ++j) {
			if (pp[i][j] != 0)
				++num;
		}
	}
	return num;
}
 
int main()
{
    freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
	int n, m;
	cin >> n >> m;
 
	int** arr = new int*[n];
	for (int i = 0; i < n; ++i)
		arr[i] = new int[n];
 
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < n; ++j) {
			cin >> arr[i][j];
		}
	}
	
	cout << m << " "
		<< out(arr, n, m - 1) << " "
		<< in(arr, n, m - 1) << endl
		<< num(arr, n);
 
	for (int i = 0; i < n; ++i)
		delete[] arr[i];
 
	return 0;
}

朋友的距离

在这里插入图片描述

#include <iostream>
#include<cstdio>
using namespace std;
int main(){
    freopen("dist.in","r",stdin);
    freopen("dist.out","w",stdout);
    int n;
    cin>>n;
    int G[n][n]={0};
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>G[i][j];
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(G[i][j]>=G[j][i]){
                G[j][i]=G[i][j];//或者采用max函数
            }
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cout<<G[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

P结点

在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
using namespace std;
vector<int> G[1005];
int fa[1005];
int main() {
    freopen("p.in", "r", stdin);
    freopen("p.out", "w", stdout);
    int t;
    bool f;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        int x, y;
        for (int i = 0; i < n - 1; i++) {
            cin >> x >> y;
            G[x].push_back(y);
            fa[y] = x;
        }
        
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            f = true;
            for (int j = 0; j < G[i].size(); j++) {
                if (G[i].size() < G[G[i][j]].size()) {
                    f = false;
                    break;
                }
            }
            if (f && G[i].size() >= G[fa[i]].size()) {
                ans++;
            }
        }
        
        cout << ans << endl;
        for (int i = 1; i <= n; i++) {
            vector<int>().swap(G[i]);
        }
        memset(fa, 0, sizeof(fa));
    }
    return 0;
}

连通块数量

#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
vector<int> G[20005];//!!!size问题
bool vis[20005];//!!!size问题
void dfs(int u) {
    vis[u] = true;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (!vis[v]) {
            dfs(v);
        }
    }
}
int main() {
    freopen("block.in","r",stdin);
    freopen("block.out","w",stdout);
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(!vis[i]){//边判断有无访问过,边进行搜索
            cnt++;
            dfs(i);
        }
    }
    cout<<cnt<<endl;
    return 0;
}

下午茶时间

在这里插入图片描述

#include<iostream>
#include<cstdio>
using namespace std;
int f[50005];
int getf(int v)
{
	return f[v]==v ? v:getf(f[v]); 
}
void merge(int v,int u)
{
	int t1=getf(v);
	int t2=getf(u);
	if(t1!=t2)
	f[t2]=t1;
	return;
}
int main()
{
    freopen("tea.in","r",stdin);
    freopen("tea.out","w",stdout);
	int i,x,y,n,m,s;
	while(scanf("%d %d %d", &n,&m,&s)!=EOF)
	{
		for(i=1; i<=n; i++)
	    f[i]=i; 
		for(i=1; i<=m;i++)
		{
			scanf("%d %d", &x,&y);
			merge(x,y);
		}
		for(i=1; i<=s; i++)
		{
			scanf("%d %d", &x,&y);
			if(getf(x)==getf(y))
			printf("Y\n");
			else
			printf("N\n");
		}
	}
	return 0;
}

家谱

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> son[100005];
int ans[100005];
bool vis[100005];
int dfs(int x){//dfs函数返回x节点的直系后代数
    int res=0;
    for(int i=0;i<son[x].size();i++){
        res+=dfs(son[x][i]);//遍历x节点的所有儿子,求出所有的儿子的直系后代数
    }
    ans[x]=res;
    return res+1;//x的孩子的直系后代数+1
}
int main(){
    freopen("family.in","r",stdin);
    freopen("family.out","w",stdout);
    cin>>n;
    for(int i=0;i<n-1;i++){
        int x,y;
        cin>>x>>y;
        son[x].push_back(y);//x的孩子为y
        vis[y]=true;//y有父亲,标记为true,表示不是根节点
    }
    int u;
    for(int i=1;i<=n;i++){//找根节点
        if(!vis[i]){
            u=i;
            break;
        }
    }
    dfs(u);
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<endl;
    }
    return 0;
}

联合权值

#include<bits/stdc++.h>

#define ll long long
#define MAXN 500010
#define N 201
#define INF 0x3f3f3f3f
#define gtc() getchar()

using namespace std;

template <class T>
inline void read(T &s){
	s = 0; T w = 1, ch = gtc();
	while(!isdigit(ch)){if(ch == '-') w = -1; ch = gtc();}
	while(isdigit(ch)){s = s * 10 + ch - '0'; ch = gtc();}
	s *= w;
}

template <class T>
inline void write(T x){
    if(x < 0) putchar('-'), x = -x;
	if(x > 9) write(x/10);
    putchar(x % 10 + '0');
}

const int mod = 10007;
struct node{
	int y, ne;
}e[MAXN];
int lin[MAXN], len = 0;
inline void add(int x, int y){
	e[++len].y = y, e[len].ne = lin[x], lin[x] = len;
}

int n;
int d[MAXN];
int sum[MAXN];
int all = 0, ans = 0;

void bfs(int x){
	int fmx = 0, smx = 0;
	int sum1 = 0, sum2 = 0;
	for(int i = lin[x]; i; i = e[i].ne){
		int y = e[i].y;
//		printf("%d ", y);
		sum1 = (sum1 + d[y]) % mod;
		sum2 = (sum2 + d[y] * d[y]) % mod; 
		if(d[y] > fmx){
			smx = fmx, fmx = d[y];
		}
		else if(d[y] > smx) smx = d[y];
	}
//	puts("");
	ans = max(ans, fmx * smx);
	sum1 = sum1 * sum1 % mod; 
	all +=  (sum1 - sum2 + mod) % mod;
}
int main()
{
    freopen("link.in","r",stdin);
    freopen("link.out","w",stdout);
	read(n);
	int x, y;
	for(int i = 1; i < n; ++i){
		read(x), read(y);
		add(x, y), add(y, x);
	}
	for(int i = 1; i <= n; ++i) read(d[i]);
	for(int i = 1; i <= n; ++i) bfs(i);
	all %= mod; 
	cout << ans << ' ' << all << endl;
	return 0;
}

质因数分解

在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
    freopen("prime.in","r",stdin);
    freopen("prime.out","w",stdout);
    int a,i,j,max;
    scanf("%d",&a);
    for(i=2;i<sqrt(a);i++){
        if(a%i==0){
            j=a/i;
            break;
        }
    }
    if(i>j){
        max=i;
    }
    else{
        max=j;
    }
    printf("%d",max);
    return 0;
}

笨小猴

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
 
int pd(int n){
    if (n == 0 || n == 1){
        return false;
    }
    for (int i = 2;i <= sqrt(n);i++){
        if (n % i == 0){
            return false;
        }
    }
    return true;
}
 
int main(){
    freopen("word.in","r",stdin);
    freopen("word.out","w",stdout);
    string n;
    cin >> n;
    int a[27],zhi,len = n.size(),max = -1,min = 101;
    memset(a,0,sizeof(a));
    for (int i = 0;i < len;i++){
        a[(int)n[i] - 96]++;
    }
    for (int i = 1;i < 26;i++){
        if (a[i] > max){
            max = a[i];
        }
        if (a[i] < min && a[i] != 0){
            min = a[i];
        }
    }
    if (pd(max - min)){
        cout << "Lucky Word" << endl;
        cout << max - min;
    }
    else{
        cout << "No Answer" << endl;
        cout << "0";
    }
}

最大公约数与最小公倍数

输入二个正整数 x,y求出满足下列条件的 P,QP,Q 的个数。条件:
P,QP,Q 是正整数
要求 P,Q 以 x 为最大公约数,以 y 为最小公倍数。

试求:满足条件的所有可能的两个正整数的个数。

#include<stdio.h>
int gcd(int a,int b){
	return a%b==0 ? b : gcd(b,a%b);
}
int lcm(int a,int b){
	return (a*b)/gcd(a,b);
}
int main(){
    freopen("gcd.in","r",stdin);
    freopen("gcd.out","w",stdout);
	int i,j,gcb1,lcm1,cnt=0;
	scanf("%d %d",&gcb1,&lcm1);
	for(i=gcb1;i<=lcm1;++i){
		for(j=gcb1;j<=lcm1;++j){
			if(gcb1==gcd(i,j)&&lcm1==lcm(i,j)){
				cnt++;				
			}
		}
	}
	printf("%d",cnt);
	return 0;
}

比例简化

在这里插入图片描述

#include <iostream>
#include<cstdio>
using namespace std;
int a,b,ans1,ans2,l;
int gcd(int x,int y)
{
    if(y==0) 
        return x;
    return gcd(y,x%y);
}
int main()
{
    freopen("ratio.in","r",stdin);
    freopen("ratio.out","w",stdout);
    scanf("%d%d%d",&a,&b,&l);
    ans1=l;ans2=1;
    for(int i=1;i<=l;i++)
        for(int j=1;j<=l;j++)
            if(gcd(i,j)==1 && i*b>=j*a && i*ans2<j*ans1)
                ans1=i,ans2=j;
    printf("%d %d",ans1,ans2);
    return 0;
}

回文数

在这里插入图片描述

#include<iostream>
#include<cstdio>
using namespace std;
int b;

string work(int x)
{
	string zfc="";
	char bz[1];
	int mod;
	while (x>=b)
	{
		mod=x%b;
		if (mod>=10)
		{
			bz[0]=(char)'A'+mod%10;
			zfc=bz[0]+zfc;
		} else
		{
			bz[0]=(char)mod+'0';
			zfc=bz[0]+zfc;
		}
		x=x/b;
	}
	if (x>=10)
	{
		bz[1]=(char)'A'+(x%10);
		zfc=bz[1]+zfc;
	} else
	{
		bz[1]=(char)x+'0';
		zfc=bz[1]+zfc;
	}
	return zfc;
}

bool check(string s)
{
	int l=s.length(),bz=0;
	if (l==2)
	{
		if (s[0]!=s[1]) return false; else return true;
	}
	for (int i=l;i>=1;i--)
		s[i]=s[i-1];
	for (int i=1;i<=l/2;i++)
		if (s[i]!=s[l-i+1])
		{
			bz=1;
			break;
		}
	if (bz==1) return false;
	return true;
}

int main()
{
    freopen("square.in","r",stdin);
    freopen("square.out","w",stdout);
	scanf("%d",&b);
	for (int i=1;i<=300;i++)
	{
		string p=work(i*i);
		if (check(p)==true) 
		{
			string w=work(i);
			cout<<w<<' '<<p<<endl;
		}
	}
	return 0;
}
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彭祥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值