NUAA模拟赛复刻题解

A. Spit Problem

题目链接

题意

题目给定了 n n n 个点,每个点都有位置 x i x_i xi 和系数 d i d_i di,求有没有两个点的编号 i , j i,j i,j i ≠ j i\neq j i=j)使得 x i + d i = x j x_i+d_i=x_j xi+di=xj 而且 x j + d j = x i x_j+d_j=x_i xj+dj=xi

思路

  1. 定义两个数组分别存放位置 x i x_i xi和系数 d i d_i di,并计算两个数的和
  2. 在外层循环中遍历数组a,在内层循环中遍历数组b,判断s[i]是否等于a[j]且a[j]+b[j]是否等于a[i],如果满足则输出YES,否则输出NO。

算法:双重循环模拟

时间复杂度

O ( n 2 ) O(n^2) O(n2)

实现步骤
  1. x
  2. x
  3. x
代码
#include <iostream>
using namespace std;

int n;

int main() {
    cin >> n;
    int a[n],b[n],s[n];
    for (int i = 0; i < n; i++) {        
        scanf("%d %d", &a[i],&b[i]);
		s[i]=a[i]+b[i];
    }    
    for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {         
        	if(s[i]==a[j]&&a[j]+b[j]==a[i]){
        		cout<<"YES";
        		return 0;
        	}        	
		}
    }   
    cout<<"NO";

    return 0;
}

 

B. Extra-terrestrial Intelligence

题目链接

题意

给定一 01 01 01 序列,试问其中的 1 1 1 是否等距.若等距则输出 YES ,否则输出 NO 。

思路

  1. 首先去除掉字符串中最后一个’1’后面的’0’。
  2. 遍历整个字符串,首先把’0’处在临时数组temp中标计为’-1’。然后计算每个’1’之间的距离,存储到临时数组temp中,
  3. 遍历整个temp数组,判断除了最后一个’1’外的所有距离是否相等。

坑点

  1. 最后一个’1’没有距离能够计算,判断的时候要直接跳过
  2. 要记得加上
freopen("input.txt","r",stdin); 
freopen("output.txt","w",stdout); 
  1. 遍历到’0’的时候要记得在temp中标记

算法:双重循环模拟

时间复杂度

O ( n 2 ) O(n^2) O(n2)

实现步骤
  1. 定义两个变量n和a,其中n表示序列的长度,a表示序列中的元素。
  2. 使用freopen函数将输入和输出重定向到input.txt和output.txt文件。
  3. 使用cin函数读取序列中的元素,并将它们存储在数组a中。
  4. 使用n1和for循环找到序列中第一个1的位置。
  5. 使用for循环遍历序列中的所有元素,并将1的位置存储在数组temp中。
  6. 使用for循环遍历数组temp,并判断两个相邻的1之间的间隔是否相等。如果两个相邻的1之间的间隔不相等输出NO,否则输出YES。
代码
#include <iostream>
#include <string.h> 
using namespace std;

int main() {
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	int n;
	cin>>n;
	char a[n];
	int temp[n];
	cin>>a;
	int n1=n;
	for(int i=n1-1;i>=0;i--){
		if(a[i]=='1'){
			break;
		}
		else if(a[i]=='0'){
			n--;
		}
	}
	for(int j=0;j<n;j++){
		if(a[j]=='1'){
			if(j==n-1){
				temp[j]=0;
			}
			for(int k=j+1;k<n;k++){		
				if(a[k]=='1'){
					temp[j]=k-j-1;
					break;
				}
			}
		}	
		else if(a[j]=='0'){
			temp[j]=-1;
		}	
	}
	
	for(int i=0;i<n;i++){
		if(temp[i]!=-1){
			for(int j=i+1;j<n-1;j++){			
				if(temp[j]!=temp[i]&&temp[j]!=-1){
					cout<<"NO"<<endl;
					return 0;
				}
			}
		}
	}
	cout<<"YES"<<endl;
    return 0;
}

 

C. Fortune Telling

题目链接

题意

给出一组数并计算这组数的最大奇数和

思路

  1. 将一组数输入,计算总和
  2. 对数进行冒泡排序
  3. 判断总和是否是奇数,不是就减去最小的奇数

坑点

  1. 要求一组数中的最大奇数和,而不是两个数的最大奇数和
  2. 偶数-奇数=奇数

算法:冒泡排序

时间复杂度

O ( n 2 ) O(n^2) O(n2)

实现步骤
  1. 首先,定义变量n、jishu、sum,分别表示输入的数字个数、奇数值、总和。
  2. 使用cin读取n的值。
  3. 定义数组a,大小为n+5,用于存储输入的数字。
  4. 使用for循环读取n个数字,并将其累加到sum中。
  5. 使用双重循环(冒泡排序)对数组a进行排序,使得数组中的数字按照非递减顺序排列。
  6. 使用for循环遍历数组a,找到第一个奇数值,并将其赋值给jishu。
  7. 判断sum的奇偶性,如果sum是偶数,则进行进一步判断。
  8. 如果jishu不为0,则将jishu从sum中减去。
  9. 如果jishu为0,则输出jishu并返回。
  10. 输出sum的值。
代码
#include <iostream>
using namespace std;

int main() {
	int n,jishu=0; 
	int sum=0;
	cin>>n;
	int a[n+5];
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		sum+=a[i];
	}
	for(int i=0;i<n;i++){
		for(int j=n-1;j>=i;j--){
			if(a[i]>=a[j]){
				int temp=a[j];
				a[j]=a[i];
				a[i]=temp;
			}
		}
	}
	for(int i=0;i<n;i++){
		if(a[i]%2!=0){
			jishu=a[i];
			break;
		}
	}
	if(sum%2==0) {
		if(jishu!=0){
			sum-=jishu;	
		}
		else{
			cout<<jishu;
			return 0;
		}
	}
	cout<<sum;
    return 0;
}

 

D. I_love_%username%

题目链接

题意

给出一组数,遍历这组数,计算这组数中超越当前最大值或最小值的次数。

思路

  1. 输入需要判断的数组
  2. 遍历整组数,将第一个数定义为初始的最大/最小值
  3. 计算这组数中超越最大最小数的次数,并更新最大/最小数

坑点

  1. 记得更新最大/最小数

算法:模拟

时间复杂度

O ( n ) O(n) O(n)

实现步骤
  1. 首先,定义变量n、count1、count2,分别表示输入的数字个数、比最大值大的元素数量、比最小值小的元素数量。
  2. 使用cin读取n的值。
  3. 定义数组a,大小为n,用于存储输入的数字。
  4. 使用for循环读取n个数字,并将其存储到数组a中。
  5. 初始化变量max和min为数组a的第一个元素。
  6. 使用for循环遍历数组a,比较每个元素与当前的最大值和最小值。
  • 如果当前元素大于最大值,更新最大值,并将count1加一。
  • 如果当前元素小于最小值,更新最小值,并将count2加一。
  1. 输出count1和count2的和,表示比最大值大和比最小值小的元素的总数量。
  2. 程序结束。
代码
#include <iostream>
using namespace std;

int main() {
	int n,count1=0,count2=0;
	cin>>n;
	int a[n];
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	int max=a[0],min=a[0];
	for(int i=0;i<n;i++){
		if(a[i]>max){
			max=a[i];
			count1++;
		}
		else if(a[i]<min){
			min=a[i];
			count2++;
		}
	}
	cout<<count1+count2<<endl;
    return 0;
}

 

E. A Piece of Cake

题目链接

题意

输入:第一个整数是 a [ 0 ] a[0] a[0]。之后 a [ 0 ] a[0] a[0]个整数 a [ 1 ] a[1] a[1] a [ 2 ] , . . . . . . , a [ a [ 0 ] ] a[2],......,a[a[0]] a[2]......a[a[0]]

输出:一个整数= a [ 1 ] a[1] a[1] + 2 a [ 2 ] a[2] a[2] + 3 x a [ 3 ] a[3] a[3] + … + a [ 0 ] a[0] a[0] x a [ a [ 0 ] ] a[a[0]] a[a[0]] a [ 0 ] a[0] a[0]<=100, a [ i ] a[i] a[i]<=1000

思路

  1. 对输入的数进行计算即可

算法:

时间复杂度

O ( n ) O(n) O(n)

实现步骤
  1. 首先,定义变量n和sum,分别表示输入的整数个数和最终的和。
  2. 使用cin读取n的值。
  3. 定义数组a,大小为n。
  4. 使用for循环读取n个整数,并将其存储到数组a中。
  5. 使用for循环遍历数组a,对于每个元素a[i],将其与其下标i相乘,并累加到sum中。
  6. 输出sum的值。
  7. 程序结束。
代码
#include <iostream>
using namespace std;
//一个整数=a[1] + 2 x a[2] + 3 x a[3] + ...... + a[0] x a[a[0]]
int main() {
	int n;
	cin>>n;
	int sum=0,a[n];
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++){
		sum+=a[i]*i;
	}
	cout<<sum;
    return 0;
}

F.B3679 [语言月赛202211] Zone Selection

题目链接

题意

分别给定 n n n 个坐标
( x i xi xi, y i yi yi​), k k k个坐标 ( x i xi xi​, y i yi yi), T T T个坐标 ( x i xi xi, y i yi yi),保证 k k k 个坐标在之前的 n n n 个坐标中出现过。
对第三组数据 T T T 个坐标中的每个坐标,求出第一组数据 n n n 个坐标中与之最近的坐标是否在第二组 k k k 个坐标中。

思路

  1. 使用结构体存储坐标以及标记
  2. 定义函数计算距离
  3. 根据询问次数进行循环判断

坑点

  1. 计算距离时不用开平方,避免误差

算法:结构体+函数+模拟

时间复杂度

O ( n ∗ t ) O(n * t) O(nt)

n是输入的点的数量,t是输入的查询次数。代码中有两个嵌套的循环,外层循环遍历t次,内层循环遍历n次。因此,总的执行次数与n和t的乘积成正比,时间复杂度为 O ( n ∗ t ) O(n * t) O(nt)

实现步骤
  1. 定义变量n、k、t,分别表示点的数量、已知点的数量和查询次数。
  2. 定义结构体node,用于存储点的坐标和标记情况。
  3. 使用cin读取n、k和t的值。
  4. 使用for循环读取n个点的坐标,并将其存储到结构体数组a中。
  5. 使用for循环读取k个已知点的坐标,并将对应的标记设置为1。
  6. 定义变量res,用于记录满足条件的查询次数。
  7. 使用for循环读取t个查询点的坐标。
  8. 定义变量max和ans,用于记录距离最大的点的索引和距离。
  9. 使用for循环遍历n个点,计算查询点与每个点的距离,并更新max和ans。
  10. 如果距离最大的点被标记为1,将res加1。
  11. 输出res的值。
  12. 程序结束。
代码
#include <iostream>
using namespace std;

int n,k,t;

struct node{
	int x,y;
	int flag; 
}a[1005];

int getDis(int x,int y,int z,int w){
	return (x-z)*(x-z)+(y-w)*(y-w);
}

int main() {
    cin >> n >> k >> t;
	for (int i=1;i<=n;i++){
		cin >> a[i].x >> a[i].y;
	}
	for (int i=1;i<=k;i++){
		int x,y;
		cin>>x>>y;
		for(int j=1;j<=n;j++){
			if(a[j].x==x&&a[j].y==y){
				a[j].flag=1;
			}
		}
	}
	int res = 0;
	for (int i=1;i<=t;i++){
		int x,y;
		cin>>x>>y;
		int max=-1;
		int ans;
		for(int j=1;j<=n;j++){
			if(getDis(x,y,a[j].x,a[j].y)>max){
				ans=j;
				max=getDis(x,y,a[j].x,a[j].y);
			}
		}
		if(a[ans].flag){
			++res;
		}
	}
	cout << res << endl;
    return 0;
}

P1147 连续自然数和

题目链接

题意

给出一个数,找出所有的区间和等于这个数,即整数分解

思路

  1. 首先,读取输入的整数M。
  2. 使用两个变量i和j,分别表示连续自然数段的起始和结束位置。
  3. 使用两个嵌套的循环,外层循环从1到M/2,内层循环从i+1到M/2+1。
  4. 在内层循环中,计算从i到j的连续自然数段的和sum。
  5. 如果sum等于M,则输出i和j。
  6. 程序结束。

坑点

  1. 注意两个循环结束的位置

算法:循环

时间复杂度

O ( M 2 ) O(M^2) O(M2)

时间复杂度为 O ( M 2 ) O(M^2) O(M2),其中 M M M是输入的整数。由于存在两个嵌套的循环,外层循环的迭代次数是M/2,内层循环的迭代次数是M。因此,总的执行次数是M/2 * M = M2/2,时间复杂度为O(M2)。

实现步骤
  1. 首先,定义变量M,用于存储输入的整数。
  2. 使用cin读取M的值。
  3. 使用两个嵌套的for循环,外层循环控制整数i的范围从0到M/2,内层循环控制整数j的范围从i到M-1。
  4. 在内层循环中,计算从i到j的整数之和sum,并判断sum是否等于M。
  5. 如果sum等于M,则输出i和j的值。
  6. 程序结束。
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int M,i,j;
	cin>>M;
	for(i=0;i<=M/2;i++)
	{
		int sum=0;
		for(j=i;j<=M-1;j++)
		{
			sum+=j;
			if(sum>=M){
				break;	
			} 
		}
		if(sum==M){
			cout<<i<<" "<<j<<endl;	
		} 
	}
	return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值