2020 CCPC Wannafly Winter Camp Day1
https://ac.nowcoder.com/acm/contest/3979
B,
密码学
题意是每行给你一个x,y表示第x个字符串对第y个字符串加密
加密的方式是将字符换成数字,然后x的字符加上y的字符模52再变回字符。如果x小于y,则你的x将重复直至大于等于y
模拟,不过你得倒序模拟
#include<bits/stdc++.h>
using namespace std;
string s[1001];
int x[1001],y[1001];
int getnum(char c)
{
if(c>='a'&&c<='z') return c-'a';
else return c-'A'+26;
}
char getword(int x)
{
if(x<26) return 'a'+x;
else return x-26+'A';
}
int main()
{
// cin>>s[1]>>s[2];
// cout<<s[1]<<s[2]<<endl;
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)cin>>x[i]>>y[i];
for(int i=1;i<=n;i++)cin>>s[i];
for(int i=m;i>=1;i--){
int l=x[i],r=y[i];
int sz1=s[l].size();
int sz2=s[r].size();
for(int j=0;j<sz2;j++){
int t=getnum(s[l][j%sz1]),t2=getnum(s[r][j]);
s[r][j]=getword((t2-t+52)%52);
}
}
for(int i=1;i<=n;i++) cout<<s[i]<<endl;
}
H
首先我们得知的是gcd(k,y)的值必须的是唯一,你不能出现gcd(y,其他数)==gcd(y,k)这样就不能用来判断k是不是他给的x;
好了已经知道gcd(k,y)是唯一的,接下来就是其他的东西了
既然是唯一的就得避免gcd出来的值是1,因为这样的话当k是质数,y可以是1,y是质数也可以,不满足题目;
故你的y必须是k的倍数,这样当k是质数时也不出问题,所以ans=k;(基础的一倍)
接下来就是y必须是p的倍数,(p为素数且pk<=n)因为p是素数所以在gcd时不影响他的结果,这样就会导致A给了B是k,给你pk,当时通过gcd你无法正确判断了(gcd(y,k)=gcd(y,pk))
所以我们需要将素数部分全部乘起来再乘以ans,
由于特殊情况当500内的素数全部相乘,数字会超大
我们用大数相乘
#include<bits/stdc++.h>
using namespace std;
int p[505], n, m, i, j, t, k, l, a[2000];
bool vis[505];
void mul(int n)
{
for(int i=0;i<1000;i++) a[i]*=n;
for(int i=0;i<1000;i++){
a[i+1]+=a[i]/10000;
a[i]=a[i]%10000;
}
}
void prin()
{
int i=1000;
while(i>=0&&!a[i]) i--;
printf("%d",a[i--]);
while(i>=0) printf("%04d",a[i--]);
}
int main() {
//freopen("in.txt", "r", stdin);
n = 500;
for (i = 2; i <= n; i++) { //线筛
if (!vis[i]) p[m++] = i;
for (j = 0; j < m && i*p[j] <= n; j++) {
vis[i*p[j]] = 1;
if (i%p[j] == 0) break;
}
}
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &k);
memset(a, 0, sizeof(a));
a[0] = l = 1;
for (i = 0; i < m && k*p[i] <= n; i++) mul(p[i]);
mul(k);
// for (i = l - 1; ~i; i--) printf("%d", a[i]);
prin();
puts("");
}
}
第k大数查询
通过二分这个值
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
const int maxn = 1e5 + 5;
LL a[maxn], b[maxn];
LL n, m, k;
bool che(LL mid) {
LL num = 0;
for (int i = 1; i <= m; i++) {
if (b[i] == 0) num += mid < 0 ? n : 0;
if (b[i] < 0) num += lower_bound(a + 1, a + n + 1, ceil((double)mid / b[i])) - (a + 1);
if (b[i] > 0) num += n - ((upper_bound(a + 1, a + n + 1, floor((double)mid / b[i]))) - (a + 1));
}
return num <= k;
}
int main() {
cin >> n >> m >> k;
k--;
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
for (int i = 1; i <= m; i++) scanf("%lld", &b[i]);
sort(a + 1, a + n + 1);
sort(b + 1, b + m + 1);
LL l = -1e13, r = 1e13;
while (l + 1 < r) {
LL mid = (l + r) >> 1;
if (che(mid))r = mid;
else l = mid;
}
cout << r << endl;
return 0;
}
浙公网安备 33010602011771号