B-Random
https://ac.nowcoder.com/acm/contest/120563/B
题意:给定一个长度为n的数组,从中选出两个不同位置的数,要求两个数的最大公约数大于1,如果存在这样的一对元素,输出它们的位置(或值);如果不存在,输出-1。
特殊的:数组元素是在范围内独立均匀随机生成
思路:这题可以直接暴力,只要找到两个偶数就可以直接输出,他们的gcd最小为2,原因是独立均匀随机生成,比如数组长度是200000,每个数是偶数的概率为0.5,就是有100000个偶数,把200000个数每31个分成一组,就是有6452个组,然后把100000偶数均匀分在这些组里就是每个组有15个偶数,那必然有两个偶数距离小于30
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
for(int i=0;i<t;i++)
{
long long n;
cin>>n;
vector<long long>arr(n);
for(long long j=0;j<n;j++)
{
cin>>arr[j];
}
int f=0;
for(long long j=0;j<n&&!f;j++)
{
for(long long m=j+1;m<n&&!f;m++)
{
if(__gcd(arr[j],arr[m])>1)
{
cout<<arr[j]<<" "<<arr[m]<<endl;
f=1;
}
}
}
if(f==0)
{
cout<<-1<<endl;
}
}
return 0;
}
H
https://ac.nowcoder.com/acm/contest/120563/H
题意:给出A,B两点,让你在横坐标上找到一个点O(x,0),使得这三个点组成面积为2的三角形,找出一个x即可,找不到输出no answer
思路:三角形的面积知道三个点的坐标就用向量的叉乘来算,|((xa-x),ya)((xb-x),yb)|/2=2, 所以|((xa-x),ya)((xb-x),yb)|=4,x=4+xbya-xayb/(ya-yb)或-4+xbya-xayb/(ya-yb),需要分类判断ya是否等于yb,再算出x的值
#include<bits/stdc++.h>
using namespace std;
int main()
{
int xa, ya, xb, yb;
cin >> xa >> ya >> xb >> yb;
int D = ya - yb;
long double C = (long long)xb * ya - (long long)xa * yb;
if (D == 0) {
if (abs(C) == 4) {
cout << fixed << setprecision(12) << 0.0 << endl;
} else {
cout << "no answer" << endl;
}
} else {
long double x1 = C - 4.0;
x1 /= D;
long double x2 =C + 4.0;
x2 /= D;
cout << fixed << setprecision(12) << x1<< endl;
}
return 0;
}
F
https://ac.nowcoder.com/acm/contest/120563/F
题意:有一个 2 行 n 列 的网格,所有格子初始为空,小小红从左上角 (1, 1) 出发,每次可以向上下左右相邻格子移动一步,且始终选择最短步数到达第 n 列的任意空格子。 小红和小紫轮流在空且非起点的格子上放置障碍,要求放置后仍存在从起点到第 n 列的路径;若无法放置满足条件的障碍,博弈结束。 两人都按最优策略行动:小红希望最终最短步数尽量小,小紫希望它尽量大。
思路:小小红每次以最小路径走就是说最好走直线,小红希望小小红走的最少,就要把障碍摆在上面或者下面,使小小红以直线走,而小紫希望他走的多,就要把障碍摆在小小红的前面,使小小红往上或者下走,可以得到下图
按照规律可得最短路为 n-1+n/5
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long t;
cin>>t;
for(long long i=0;i<t;i++)
{
long long n;
cin>>n;
cout<<n-1+n/5<<endl;
}
return 0;
}
C
https://ac.nowcoder.com/acm/contest/120563/C
题意:给定一个仅由字符 0 和 1 组成的字符串 s。 你可以进行任意次操作:选择一个非空子序列(该子序列中任意两个相邻元素必须不同),对这个子序列进行01 反转(即 0 变 1,1 变 0)。 目标是:通过最少次数的操作,使得最终字符串 s 中任意两个相邻元素都不相同。 输出这个最少操作次数。
思路:最终的字符串必然是1010...或0101...则要比较变为这两种字符串的次数,先将原本的字符串与最终的字符串比较,标记出不同的字符,算将这些字符翻转的最小次数。比如110110,将这个字符串翻转的次数可以先开两个变量a,b存末尾为0的子序列数和末尾为1的子序列数,如果遍历到1,则需要把它接到末尾为0的序列后面,则放完后a--,b++,遍历到0则相反,不断更新末尾为0和1的序列数,最终a+b就是翻转次数
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long t;
cin>>t;
for(long long i=0;i<t;i++)
{
long long n;
cin>>n;
string arr;
cin>>arr;
vector<char> mp1;
vector<char> mp2;
char tar;
char f;
for(long long j=0;j<n;j++)
{
if((j+1)%2==0)
{
tar='1';
f='0';
}
else
{
tar='0';
f='1';
}
if(arr[j]!=tar)
{
mp1.push_back(arr[j]);
}
if(arr[j]!=f)
{
mp2.push_back(arr[j]);
}
}
long long a=0;//计0
long long b=0;//计1
long long x=0;//计0
long long y=0;//计1
for(char m:mp1)
{
if(m=='0')
{
if(b==0)
{
a++;
}
else
{
b--;
a++;
}
}
else
{
if(a==0)
{
b++;
}
else
{
a--;
b++;
}
}
}
for(char l:mp2)
{
if(l=='0')
{
if(y==0)
{
x++;
}
else
{
y--;
x++;
}
}
else
{
if(x==0)
{
y++;
}
else
{
x--;
y++;
}
}
}
cout<<min(a+b,x+y)<<endl;
}
return 0;
}

京公网安备 11010502036488号