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 。
思路
- 定义两个数组分别存放位置 x i x_i xi和系数 d i d_i di,并计算两个数的和
- 在外层循环中遍历数组a,在内层循环中遍历数组b,判断s[i]是否等于a[j]且a[j]+b[j]是否等于a[i],如果满足则输出YES,否则输出NO。
算法:双重循环模拟
时间复杂度
O ( n 2 ) O(n^2) O(n2)
实现步骤
- x
- x
- 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’后面的’0’。
- 遍历整个字符串,首先把’0’处在临时数组temp中标计为’-1’。然后计算每个’1’之间的距离,存储到临时数组temp中,
- 遍历整个temp数组,判断除了最后一个’1’外的所有距离是否相等。
坑点
- 最后一个’1’没有距离能够计算,判断的时候要直接跳过
- 要记得加上
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
- 遍历到’0’的时候要记得在temp中标记
算法:双重循环模拟
时间复杂度
O ( n 2 ) O(n^2) O(n2)
实现步骤
- 定义两个变量n和a,其中n表示序列的长度,a表示序列中的元素。
- 使用freopen函数将输入和输出重定向到input.txt和output.txt文件。
- 使用cin函数读取序列中的元素,并将它们存储在数组a中。
- 使用n1和for循环找到序列中第一个1的位置。
- 使用for循环遍历序列中的所有元素,并将1的位置存储在数组temp中。
- 使用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
题意
给出一组数并计算这组数的最大奇数和
思路
- 将一组数输入,计算总和
- 对数进行冒泡排序
- 判断总和是否是奇数,不是就减去最小的奇数
坑点
- 要求一组数中的最大奇数和,而不是两个数的最大奇数和
- 偶数-奇数=奇数
算法:冒泡排序
时间复杂度
O ( n 2 ) O(n^2) O(n2)
实现步骤
- 首先,定义变量n、jishu、sum,分别表示输入的数字个数、奇数值、总和。
- 使用cin读取n的值。
- 定义数组a,大小为n+5,用于存储输入的数字。
- 使用for循环读取n个数字,并将其累加到sum中。
- 使用双重循环(冒泡排序)对数组a进行排序,使得数组中的数字按照非递减顺序排列。
- 使用for循环遍历数组a,找到第一个奇数值,并将其赋值给jishu。
- 判断sum的奇偶性,如果sum是偶数,则进行进一步判断。
- 如果jishu不为0,则将jishu从sum中减去。
- 如果jishu为0,则输出jishu并返回。
- 输出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%
题意
给出一组数,遍历这组数,计算这组数中超越当前最大值或最小值的次数。
思路
- 输入需要判断的数组
- 遍历整组数,将第一个数定义为初始的最大/最小值
- 计算这组数中超越最大最小数的次数,并更新最大/最小数
坑点
- 记得更新最大/最小数
算法:模拟
时间复杂度
O ( n ) O(n) O(n)
实现步骤
- 首先,定义变量n、count1、count2,分别表示输入的数字个数、比最大值大的元素数量、比最小值小的元素数量。
- 使用cin读取n的值。
- 定义数组a,大小为n,用于存储输入的数字。
- 使用for循环读取n个数字,并将其存储到数组a中。
- 初始化变量max和min为数组a的第一个元素。
- 使用for循环遍历数组a,比较每个元素与当前的最大值和最小值。
- 如果当前元素大于最大值,更新最大值,并将count1加一。
- 如果当前元素小于最小值,更新最小值,并将count2加一。
- 输出count1和count2的和,表示比最大值大和比最小值小的元素的总数量。
- 程序结束。
代码
#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
思路
- 对输入的数进行计算即可
算法:
时间复杂度
O ( n ) O(n) O(n)
实现步骤
- 首先,定义变量n和sum,分别表示输入的整数个数和最终的和。
- 使用cin读取n的值。
- 定义数组a,大小为n。
- 使用for循环读取n个整数,并将其存储到数组a中。
- 使用for循环遍历数组a,对于每个元素a[i],将其与其下标i相乘,并累加到sum中。
- 输出sum的值。
- 程序结束。
代码
#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 个坐标中。
思路
- 使用结构体存储坐标以及标记
- 定义函数计算距离
- 根据询问次数进行循环判断
坑点
- 计算距离时不用开平方,避免误差
算法:结构体+函数+模拟
时间复杂度
O ( n ∗ t ) O(n * t) O(n∗t)
n是输入的点的数量,t是输入的查询次数。代码中有两个嵌套的循环,外层循环遍历t次,内层循环遍历n次。因此,总的执行次数与n和t的乘积成正比,时间复杂度为 O ( n ∗ t ) O(n * t) O(n∗t)。
实现步骤
- 定义变量n、k、t,分别表示点的数量、已知点的数量和查询次数。
- 定义结构体node,用于存储点的坐标和标记情况。
- 使用cin读取n、k和t的值。
- 使用for循环读取n个点的坐标,并将其存储到结构体数组a中。
- 使用for循环读取k个已知点的坐标,并将对应的标记设置为1。
- 定义变量res,用于记录满足条件的查询次数。
- 使用for循环读取t个查询点的坐标。
- 定义变量max和ans,用于记录距离最大的点的索引和距离。
- 使用for循环遍历n个点,计算查询点与每个点的距离,并更新max和ans。
- 如果距离最大的点被标记为1,将res加1。
- 输出res的值。
- 程序结束。
代码
#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 连续自然数和
题意
给出一个数,找出所有的区间和等于这个数,即整数分解
思路
- 首先,读取输入的整数M。
- 使用两个变量i和j,分别表示连续自然数段的起始和结束位置。
- 使用两个嵌套的循环,外层循环从1到M/2,内层循环从i+1到M/2+1。
- 在内层循环中,计算从i到j的连续自然数段的和sum。
- 如果sum等于M,则输出i和j。
- 程序结束。
坑点
- 注意两个循环结束的位置
算法:循环
时间复杂度
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)。
实现步骤
- 首先,定义变量M,用于存储输入的整数。
- 使用cin读取M的值。
- 使用两个嵌套的for循环,外层循环控制整数i的范围从0到M/2,内层循环控制整数j的范围从i到M-1。
- 在内层循环中,计算从i到j的整数之和sum,并判断sum是否等于M。
- 如果sum等于M,则输出i和j的值。
- 程序结束。
代码
#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;
}