SICNU ACM新生第一次考核

题目

A.最近距离(签到题)

题目

SICNU ACM新生第一次考核

思路:

只需要判断AB直线是否垂直坐标轴且F点在AB线段之间即可,若不符合:代表A、B点之间的最短路径不止一条,最终结果就为A、B两点的横纵坐标差的绝对值之和;如果符合,则代表A、B点之间的最短路径只有一条,则A到B点是需要绕过F点,则在不符合的条件上加上绕路的距离2。

代码:

#include<iostream>
#include<algorithm>

using namespace std;

int main()
{
	int t;
	scanf("%d",&t);
	
	while(t--){
		int Ax,Ay,Bx,By,Fx,Fy;
		//读入A、B、F点坐标 
		scanf("%d %d",&Ax,&Ay);
		scanf("%d %d",&Bx,&By);
		scanf("%d %d",&Fx,&Fy);
		
		int ans = abs(Bx - Ax) + abs(By - Ay);//计算A、B点的横纵坐标差的绝对值之和 
		
		if(Ax == Bx && Bx == Fx && Fy > min(Ay,By) && Fy < max(Ay,By)) ans += 2;
		//判断是否AB线段垂直与x轴且F点在AB线段之间 
		if(Ay == By && By == Fy && Fx > min(Ax,Bx) && Fx < max(Ax,Bx)) ans += 2;
		//判断是否AB线段垂直与y轴且F点在AB线段之间 
		printf("%d\n",ans);
	}	
	return 0;
}
 

B.这是一道特别简单的题目(简单数学题)

题目:

SICNU ACM新生第一次考核

思路:

让你判断一个数是否有除1以外的奇数因数,只需要将数进行完全的因数分解(分解为全为质数相乘的形式),
发现,只有当因数全为2(换句话说就是这个数是2n)时,没有除1以外的奇数因子。

代码:

#include<bits/stdc++.h>

using namespace std;

int main()
{
	long long n; 
	cin >> n;
	
	//如果n为整数,就不断/2知道其为奇数	
	while(n % 2 == 0 ){
		n /= 2;
	}
	//只需要判断这个奇数是否为1,为1证明这个数完全分解的因子全为2,反之亦然 
	if(n != 1) cout<<"YES";
	else cout<<"NO";
	
	return 0;
}

C.M78星云的字符转换(基础题)

题目:

SICNU ACM新生第一次考核

思路:

通过ASCLL码转换,将小写字符转化为大写字母,如果忘了大小写字母相差多少位的,可以输出一下小写字母减大写字母来看一下。

代码:

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

int main()
{
	char str[1010];
	//字符串读入方式 
	scanf("%s",str);
	//strlen函数求字符串长度 
	for(int i = 0 ; i < strlen(str) ; i ++){
		//根据ASCLL码小写字母比大写字母大32来转换大小写字母 
		if(str[i] >= 'a' && str[i] <= 'z') str[i] -= 32;
	}
	
	printf("%s",str);
	
	return 0;
}

D.M78星云的排队事故(前缀和板子题)

题目:

SICNU ACM新生第一次考核

思路:

基础前缀和知识运用,先进行排序,再求区间 [l,r] 的和即求 [1,r] - [1,l - 1] 的值即可。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>

using namespace std;
const int N = 1e3 + 10;

int arr[N];
int q[N];//前缀和数组 ,q[i]代表[1,i]区间中所有值的和 
int n,l,r;

int main()
{
	scanf("%d",&n);
	for(int i = 1 ; i <= n ; i ++){
		scanf("%d",&arr[i]);
	}	
	sort(arr + 1 , arr + 1 + n);//sort排序函数,也可以自己写冒泡代替 
	//求前缀和数组 
	for(int i = 1 ; i <= n ; i ++) q[i] = q[i - 1] + arr[i];
	
	scanf("%d %d",&l,&r);
	
	printf("%d",q[r] - q[l - 1]);
	return 0;
}

F.不服气的洁洁学姐(gcd)

题目:

SICNU ACM新生第一次考核

思路:

不限次数对数组任意区间减去相同的值,最终使数组所有值相同,假定减去的值为K,对数组任意 arri 可假设其减少了n次K值后变为定值s,即 arri - nK = s, 数组中每个值在变化前后均满足此式,求K的最大值,即求数组中所有减少量nK的最大公约数(gcd)。对于每一个数减少的量一定使K的倍数或为0,于是相邻两个数做差 |arra - arrb |= |(aK + s) - (bK + s) |= |(a-b)K|,所以只需要对所有相邻的两个数的差值的绝对值(不为0,为0没意思)求最大公约数即可。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>

using namespace std;
const int N = 1e6 + 10;

int arr[N],q[N];
int n;

int gcd(int a , int b)
{
	if(b == 0) return a;
	return gcd(b,a%b); 
}

int main()
{
	scanf("%d",&n);
	for(int i = 0 ; i < n ; i ++) scanf("%d",&arr[i]);
	
	int k = 0;
	//相邻两位做差,得到K的倍数 
	for(int i = 0 ; i + 1 < n ; i ++) 
		if(arr[i + 1] - arr[i])//将所有不为0的差值的绝对值存入q数组 
			q[k++] = abs(arr[i + 1] - arr[i]);
	
	int ans = q[0];
	//对k个K的倍数求最大公约数,得到结果 
	for(int i = 1 ; i  < k ; i ++) ans = gcd(ans , q[i]);
	//若ans == 0 ,代表arr数组中所有值相等,K最大值趋于无穷 
	if(ans == 0) printf("-1");
	else printf("%d",ans);
	
	return 0;
}

E.来自M78星云的小测试(进制转换+回文)

题目:

SICNU ACM新生第一次考核

思路:

将数字转化为m进制后用字符串形式存储,然后用双指针一头一尾向中间跑,不断进行比较判断是否为回文即可。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>

using namespace std;
const int N = 1e4 + 10;

int n , m; 
char q[20] = "0123456789ABCDEF";

bool check(int a)
{
	char s[100];//存储a转换为m进制后的字符串 
	int k = 0;//记录转换为字符串后的位数 
	a = a * a;
	//进行进制转换 
	while(a){
		s[k ++] = q[a % m];
		a /= m;
	}
	//从头尾向中间比较是否字符相同,若存在不同则不为回文 
	int i = 0, j = k - 1;
	while(i < j){
		if(s[i] == s[j]) i++,j--;
		else return false;//不满足回文返回false 
	}
	
	return true;
		
}

int main()
{
	scanf("%d %d",&n,&m);
	
	int ans = 0;
	for(int i = 1 ; i <= n ; i ++){
		if(check(i)) ans ++;//记录满足回文的数量 
	}
	
	printf("%d",ans);
}

G.来自M78星云的减法运算(模拟题/彩蛋题)

题目:

SICNU ACM新生第一次考核

思路:

python解法(最简单的解法):

由于python的整数没有范围限制,之间定义两个数做差即可。

代码:

a = int(input().strip())
b = int(input().strip())
print(a-b)

c/c++解法(大模拟):

用数组模拟计算过程。

代码:

#include<bits/stdc++.h>

using namespace std;

//判断A是否大于B 
bool check(string str1 , string str2)
{
	int len1 = str1.length(),len2 = str2.length();
	
	if(len1 != len2) return len1 > len2;
	
	for(int i = len1 - 1 ;i >= 0 ; i --)
		if(str1[i] != str2[i]) return str1[i] > str2[i];
	
	return true;
}

int main()
{
	
	string str1,str2;
	cin>>str1>>str2;
	int ans[1000];
	bool s = true;
	
	if(!check(str1,str2)){
		//如果A<B,交换A,B,并用s记录结果为负 
		swap(str1,str2);
		s = false;
	}
	
	int i = str1.length() - 1, j = str2.length() - 1;
	
	int k = 0,cn = 0; //k代表是否借位 
	
	//A - B的模拟计算过程 
	while(i >= 0 &&  j >= 0){
		if(str1[i] + k < str2[j]){
			
			ans[cn ++] = str1[i] - str2[j] + 10 + k ;
			k = -1;
		}else{
			ans[cn++] = str1[i] - str2[j] + k ;
			k = 0;
		}
		i--,j--;
	}
	//A的位数多余B,要将A多余位数加上 
	while(i >= 0){
		if(str1[i] - '0' + k >= 0){
			ans[cn++] = str1[i] - '0' + k;
			k = 0;
		}else{
			ans[cn++] = str1[i] - '0' + k + 10;
			k = -1;
		}
		i--;
	}
	//同理B的位数多余A,要将B多余位数加上 
	while(j >= 0){
		if(str2[j] - '0' + k >= 0){
			ans[cn++] = str2[j] - '0' + k;
			k = 0;
		}else{
			ans[cn++] = str2[j] - '0' + k + 10;
			k = -1;
		}
		j--;
	}
	
	
	if(!s) cout<<"-";
	while(!ans[cn - 1] && cn > 1) cn--;
	
	for(int i = cn - 1 ; i >= 0 ; i --)	 cout<<ans[i];

 }
上一篇:Spring DI源码分析5


下一篇:ACM-Template 2.0 by Axiomofchoice