F:已知AB两点在一条直线上,CD两点在同一条直线上,已知两条直线平行,已知AC,AD,BC,BD距离,求从AB方向看为CD还是DC
分情况讨论的方法
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int ac,ad,bc,bd;
cin >> ac >> ad >> bc >> bd;
int ans = 0;
if(ac > ad)
{
if(bd >= bc)
{
ans = 0;
}
else
{
if(ad > bd)
{
ans = 0;
}
else
ans = 1;
}
}
else
{
if(bd <= bc)
ans = 1;
else
{
if(ac > bc)
{
ans = 1;
}
else
{
ans = 0;
}
}
}
if(ans)
{
cout << "AB//CD" << endl;
}
else
{
cout << "AB//DC" << endl;
}
}
return 0;
}
大佬们的思路:
ABCD构成一个梯形,梯形具有对角线之和大于两腰之和的特点;
又或者 设AD与BC交点为O,形成OAC,OBD两个三角形,三角形两边之和大于第三边。
所以,只需要判断AD + BC是否大于AC + BD即可。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int ac,ad,bc,bd;
cin >> ac >> ad >> bc >> bd;
if(ad + bc > ac + bd)
{
cout << "AB//CD" << endl;
}
else cout << "AB//DC" << endl;
}
return 0;
}
B:给你n与c,求出算式的最大值
算式每一次递归,都会乘一次c,
每一次递归的选择都是选择最大的,而值的增大来源于多个c的相乘。
所以,我们只需要让递归的层次最多即可。
所以,对于n,分解质因数,所有质因数的幂次求和就是递归次数 num。
最终结果就是c的num次方。
每一次在牛客的调试机上写筛或者唯一分解都会出段错误,真是醉了
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e6 + 50;
const long long mod = 1e9 + 7;
int zhi[maxn/2] = {0};
int vis[maxn] = {0};
int z = 0;
void oulashai()
{
for(int i = 2; i < maxn - 5; i++)
{
if(!vis[i])
{
zhi[z] = i;
z++;
}
for(int j = 0; j < z && zhi[j]*i < maxn - 5; j++)
{
vis[i*zhi[j]] = 1;
if(i % zhi[j] == 0)break;
}
}
}
long long hanshu(long long a)
{
long long ans = 0;
int t = 0;
while(t < z)
{
long long temp = zhi[t] * zhi[t];
if(temp > a) break;
while(a % zhi[t] == 0)
{
a /= zhi[t];
ans++;
}
t++;
}
if(a > 1) ans++;
return ans;
}
int quickPower(int x, int y)//快速幂加取模
{
long long result = 1; // 定义答案
while (y > 0) // 当指数大于 0 时进行幂运算
{
if (y & 1) // y 和 1 做与运算,相当于对 2 求模
{
result = (result * x) % mod;// 如果 y 为奇数,则结果只乘一个 x
}
x = x * x % mod; // x 乘二次方,下次使用
y = y >> 1; // y 右移一位,相当于除以 2
}
return result % mod; // 返回结果
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
oulashai();
int t;
cin >> t;
while(t--)
{
long long n,c;
cin >> n >> c;
long long num = hanshu(n);
long long ans = quickPower(c,num) % mod;
cout << ans << endl;
}
return 0;
}
H: 把 1~N 的数进行两两匹配,使得每组对gcd 大于 1。问最多能匹配多少对,并输出匹配。
从大到小遍历质数,遍历n以内所有质数P的倍数,选择其中没有匹配过的,两两匹配。
如果P的倍数为奇数个,就把2倍的留下(待到枚举质数为2的时候再使用)
如果为偶数个,那么两两匹配即可。
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 2e5 + 50;
int zhi[maxn/2] = {0};
int vis[maxn] = {0};
int z = 0;
void oulashai()
{
vis[0] = 1;
vis[1] = 1;
for(long long i = 2; i < maxn; i++)
{
if(!vis[i])
{
zhi[++z] = i;
}
for(long long j = 1; j <= z && zhi[j] * i < maxn; j++)
{
vis[i*zhi[j]] = 1;
if(i % zhi[j] == 0)break;
}
}
}
int flag[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
oulashai();
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for(int i = 1; i <= n; i++)
{
flag[i] = 0;
}//匹配标记
vector<int> a,b;
int ans = 0;
int pos = upper_bound(zhi + 1, zhi + 1 + z, n / 2 + 1) - zhi - 1;
// n/2 以内的最大质因数zhi[pos]
for(int i = pos; i >= 1; i--)
{//从大到小枚举所有可能的质因数
vector<int> v;
int t = zhi[i];
for(int j = t; j <= n; j += t)
{
if(!flag[j])
{
v.push_back(j);
}
}
int num = v.size();
if(num > 1)
{
ans += num / 2;
if(num % 2 == 1)
{
vector<int> t;
for(int j = 0; j < num; j++)
{
if(v[j] != 2 * zhi[i])
{
//cout << v[j] << endl;
t.push_back(v[j]);
}
}
for(int j = 0; j < t.size(); j+=2)
{
a.push_back(t[j]);
b.push_back(t[j+1]);
flag[t[j]] = 1;
flag[t[j+1]] = 1;
}
}
else
{
for(int j = 0; j < num; j+=2)
{
a.push_back(v[j]);
b.push_back(v[j+1]);
flag[v[j]] = 1;
flag[v[j+1]] = 1;
}
}
}
}
cout << ans << endl;
for(int i = 0; i < ans; i++)
{
cout << a[i] << " " << b[i] << endl;
}
}
return 0;
}