团队练习记录2024.9.28
B - Magical Subsequence
https://codeforces.com/gym/103447/problem/B
桶+stack,这里用map会TLE
stack用一次时间复杂度\(O(1)\)
\(156ms/1000ms\)
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void fio()
{
ios::sync_with_stdio();
cin.tie(0);
cout.tie(0);
}
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
ans*=x;
x*=x;
y>>=1;
}
return ans;
}
inline ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch))
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
ll a[250000];
ll n;
ll ck(ll x)
{
stack<ll>q;
ll b[250]={0};
ll ans=0;
for(ll i=1;i<=n;i++)
{
if(a[i]<x)
{
if(b[x-a[i]]>0)
{
ans++;
while(!q.empty())
{
b[q.top()]=0;
q.pop();
}
continue;
}
else
{
if(b[a[i]]==0)
{
q.push(a[i]);
}
b[a[i]]++;
}
}
}
return ans*2;
}
int main()
{
cin>>n;;
for(ll i=1;i<=n;i++)a[i]=read();
ll ans=0;
for(ll i=1;i<=200;i++)
{
ans=max(ans,ck(i));
}
printf("%lld\n",ans);
}
D. Math master
https://codeforces.com/gym/103447/problem/D
先用gcd求出最小的比例形式,然后暴力求出一个数的所有可能组合,时间复杂度为最差在2的18次方左右?
sort一遍储存的数
然后直接check查出另一个答案是否符合题目要求
第一个符合的最小的即为所求。
\(3171ms/4000ms\)
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
void fio()
{
ios::sync_with_stdio();
cin.tie(0);
cout.tie(0);
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
ans *= x;
x *= x;
y >>= 1;
}
return ans;
}
/*
inline ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch))
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}*/
ll a[3500000];
ll l = 0;
void zu(string x,ll wz,ll su)
{
for (ll i = wz + 1; i < x.size(); i++)
{
zu(x, i, su * 10 + x[i] - '0');
}
if (su > 0)
{
l++;
a[l] = su;
}
}
bool ck(string a, string b, string a1, string b1)
{
ll num[15] = { 0 };
ll num2[15] = { 0 };
ll la = a.length() - 1, la1 = a1.length() - 1, lb = b.length() - 1, lb1 = b1.length() - 1;
while (la1 >= 0) {
if (la < 0) {
if (a1[la1] == '0' && la < 0) {
num[10]++;
la1--;
continue;
}
num[a1[la1] - '0']++;
la1--;
continue;
}
if (a[la] == a1[la1]) {
la--, la1--;
continue;
}
else {
num[a1[la1] - '0']++;
la1--;
}
}
while (lb1 >= 0) {
if (lb < 0) {
if (b1[lb1] == '0' && lb < 0) {
num2[10]++;
lb1--;
continue;
}
num2[b1[lb1] - '0']++;
lb1--;
continue;
}
if (b[lb] == b1[lb1]) {
lb--, lb1--;
continue;
}
else {
num2[b1[lb1] - '0']++;
lb1--;
}
}
ll flag = 1;
for (int i = 0; i <= 9; i++) {
if (i == 0) {
ll mini = min(num[0] + num[10], num2[0] + num2[10]);
if (mini < max(num[0], num2[0])) {
flag = 0;
}
}
else if (num[i] != num2[i]) {
flag = 0;
}
}
if (flag) return true;
else return false;
}
int main()
{
fio();
ll t;
t = 1;
while (t--)
{
ll n;
cin >> n;
for (ll i = 1; i <= n; i++)
{
ll x, y;
cin >> x >> y;
ll k = gcd(x, y);
ll x1 = x / k;
ll y1 = y / k;
string h = to_string(x);
string e = to_string(y);l = 0;
for (ll u = 0; u < h.size(); u++)
{
zu(h, u, h[u] - '0');
}
//for (ll i = 1; i <= l; i++)cout << a[i] << " ";
sort(a + 1, a + 1 + l);
ll ans1=0, ans2=0;
for (ll i = 1; i <= l; i++)
{
if (a[i] % x1 == 0)
{
ll k1 = a[i] / x1;
ll y2 = y1*k1;
string jk = to_string(a[i]);
string ko = to_string(y2);
if (ck(jk,ko,h,e))
{
ans1 = a[i], ans2 = y2;
break;
}
}
}
cout << ans1 << " " << ans2 << endl;
}
}
}
E. Power and Modulo
https://codeforces.com/gym/103447/problem/E
打表可得,如果2的次方被模后会呈现一个周期,要特判后面为为0,全部数为0,数组对应位置大于2的次方的情况
然后直接找到第一个变小的数字,然后用对应的数的次方减掉它即为模数
\(218ms/1000ms\)
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
void fio()
{
ios::sync_with_stdio();
cin.tie(0);
cout.tie(0);
}
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
ans*=x;
x*=x;
y>>=1;
}
return ans;
}
/*
inline ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch))
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}*/
ll a[120000];
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
ll g=0;
ll op=0;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]==0)
op++;
if(g)
{
if(a[i]>0)
{
g=-1;
}
}
if(a[i]==0&&g==0)
{
g=1;
}
}
if(op==n)
{
cout<<1<<endl;
continue;
}
if(g==-1)
{
cout<<-1<<endl;
continue;
}
ll cnt=1;
ll x=0;
for(ll i=1;i<=n;i++)
{
if(a[i]!=cnt)
{
x=cnt-a[i];
break;
}
cnt*=2;
}
if(x<0)
{
cout<<-1<<endl;
continue;
}
if(x==0)
{
x=a[n];
}
cnt=1;
g=0;
cnt%=x;
for(ll i=1;i<=n;i++)
{
if(a[i]!=cnt)
{
g=-1;
}
cnt=(cnt%x*(2%x))%x;
}
if(g==-1)
{
cout<<-1<<endl;
}
else
{
cout<<x<<endl;
}
}
}
I. Power and Zero
https://codeforces.com/gym/103447/problem/I
二进制转换+暴力
记得没事不开\(unsigned long long\)
\(249ms/1000ms\)
#include<iostream>
using namespace std;
typedef long long ll;
void fio()
{
ios::sync_with_stdio();
cin.tie(0);
cout.tie(0);
}
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
ans *= x;
x *= x;
y >>= 1;
}
return ans;
}
/*
inline ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch))
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}*/
ll a[40];
int main()
{
fio();
ll t;
cin >> t;
// cout<<55<<endl;
while (t--)
{
ll n;
cin >> n;
for (ll i = 0; i <= 31; i++)a[i] = 0;
for (ll i = 1; i <= n; i++)
{
ll x;
cin >> x;
ll k = 1;
for (ll j = 0; j <= 31; j++)
{
if (k & x)
a[j]++;
k *= 2;
}
}
ll ans = 0;
while (1)
{
ll cnt = 0;
for (ll i = 0; i <= 31; i++)
{
if (a[i] == 0)
cnt++;
}
if (cnt == 32)
break;
ans++;
for (ll i = 0; i <= 31; i++)
{
if (a[i] > 0)
{
a[i]--;
}
else
{
for (ll j = i + 1; j <= 31; j++)
{
if (a[j] > 0)
{
a[j]--;
for(ll k = j - 1; k >= 0; k--)
{
if (k >= i)
{
a[k]++;
}
else
{
break;
}
}
break;
}
}
}
}
}
cout << ans << endl;
}
}
J. Local Minimum
https://codeforces.com/gym/103447/problem/J
统计一个数既为此行最小和此列最小的数
\(203ms/1000ms\)
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void fio()
{
ios::sync_with_stdio();
cin.tie(0);
cout.tie(0);
}
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
ans*=x;
x*=x;
y>>=1;
}
return ans;
}
inline ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch))
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
ll a[2500][2500];
ll b[2500];
ll c[2500];
int main()
{
ll n,m,f;
n=read();
m=read();
for(ll i=1;i<=n;i++)
{
ll x=99999999999;
for(ll j=1;j<=m;j++)
{
a[i][j]=read();
x=min(x,a[i][j]);
}
b[i]=x;
}
for(ll i=1;i<=m;i++)
{
ll x=99999999999;
for(ll j=1;j<=n;j++)
{
x=min(x,a[j][i]);
}
c[i]=x;
}
ll ans=0;
for(ll i=1;i<=n;i++)
{
for(ll j=1;j<=m;j++)
{
if(b[i]==a[i][j]&&c[j]==a[i][j])
ans++;
}
}
printf("%lld\n",ans);
}