Codeforces Round 1027 (Div. 3) A-F
A. Square Year
判断一个数是不是平方数即可,赛时无脑写暴力了
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
//using i128 = __int128_t;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int s;
cin>>s;
for(int i=0;i<=100;i++){
for(int j=i;j<=100;j++){
if((i+j)*(i+j)==s){
cout<<i<<" "<<j<<endl;
return;
}
}
}
cout<<-1<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
B. Not Quite a Palindromic String
如果有k对相同的数配对,则需要有(n-k*2)/2对01配对,先配对这些,在再看剩下的能不能配够k对
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
//using i128 = __int128_t;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n,k;
cin>>n>>k;
string s;
int c0=0,c1=0;
cin>>s;
for(auto ch:s){
if(ch=='0') c0++;
else c1++;
}
int tar=(n-2*k)/2;
if(c1<tar || c0<tar){
cout<<"NO\n";
return;
}
c0-=tar;
c1-=tar;
if(c1/2 + c0/2 == k){
cout<<"YES\n";
}
else cout<<"NO\n";
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
C. Need More Arrays
首先重复的元素是没用的,然后无脑dp就行了
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
//using i128 = __int128_t;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n;
cin>>n;
vector<int> a(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
}
a.erase(unique(a.begin()+1,a.end()),a.end());
int f[n+10][2];
n=a.size()-1;
f[1][1]=0;//删除第i个数,前i个数的最大值
f[1][0]=1;//不删
for(int i=2;i<=n;i++){
f[i][0]=f[i-1][1]+1;
f[i][1]=f[i-1][0];
if(a[i]>a[i-1]+1){
f[i][0]=max(f[i][0],f[i-1][0]+1);
}
}
cout<<max(f[n][1],f[n][0])<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
D. Come a Little Closer
先把所有的点用矩形框住,要删除的点一定是矩形四个角的点。
维护x,y的最大值和次大值,枚举删除一个点后,剩余点的矩形的长和宽。注意可能此时矩形内部被填满了,要多开一行或一列
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
//using i128 = __int128_t;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n;
cin>>n;
vector<int> x(n+1),y(n+1);
for(int i=1;i<=n;i++){
cin>>x[i]>>y[i];
}
if(n==1){
cout<<1<<endl;
return;
}
auto tx=x,ty=y;
sort(tx.begin()+1,tx.end());
sort(ty.begin()+1,ty.end());
int mn1x=tx[1],mn2x=tx[2];
int mx1x=tx[n],mx2x=tx[n-1];
int mn1y=ty[1],mn2y=ty[2];
int mx1y=ty[n],mx2y=ty[n-1];
int cntmnx=count(tx.begin()+1,tx.end(),mn1x);
int cntmxx=count(tx.begin()+1,tx.end(),mx1x);
int cntmny=count(ty.begin()+1,ty.end(),mn1y);
int cntmxy=count(ty.begin()+1,ty.end(),mx1y);
int ans=inf;
for(int i=1;i<=n;i++){
int lox=(x[i]==mn1x && cntmnx==1?mn2x:mn1x);
int hix=(x[i]==mx1x && cntmxx==1?mx2x:mx1x);
int loy=(y[i]==mn1y && cntmny==1?mn2y:mn1y);
int hiy=(y[i]==mx1y && cntmxy==1?mx2y:mx1y);
int dx=hix-lox+1;
int dy=hiy-loy+1;
int val=dx*dy;
int nd=n-1;
int tmp;
if(val==nd) tmp=min((dx+1)*dy,dx*(dy+1));
else tmp=val;
ans=min(ans,tmp);
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
E. Kirei Attacks the Estate
维护每个点的最大值和最小值,u的子节点v,v的最大值等于 w[v] - u 的最小值
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
//using i128 = __int128_t;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n;
cin>>n;
vector<int> w(n+10),mn(n+10,inf),mx(n+10,-inf);
vector<vector<int>> g(n+10);
for(int i=1;i<=n;i++){
cin>>w[i];
}
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
mn[0]=0;
mx[0]=0;
auto dfs = [&](auto dfs,int u,int pre)->void {
mn[u] = min({mn[u], w[u], w[u] - mx[pre]});
mx[u] = max({mx[u], w[u], w[u] - mn[pre]});
for(auto v:g[u]){
if(v==pre) continue;
dfs(dfs,v,u);
}
};
dfs(dfs,1,0);
for(int i=1;i<=n;i++){
cout<<mx[i]<<" ";
}
cout<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
F. Small Operations
x,y, 要先除掉 x 有 y 没有的因数,再乘上 y 有 x 没有的因数
设 t = gcd(x,y)
就是先除掉 x/t,再乘上 y/t
每次要找到,从1乘到 x/t 的最小合法乘法次数, 这一步可以在 x/t 的约数上dp得到
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
//using i128 = __int128_t;
const ll inf = 1e18;
const int mod = 998244353;
const int N=1e6;
/*
x,y, 要先除掉x有y没有的因数,再乘上y有x没有的因数
设 t = gcd(x,y)
就是先除掉x/t的因数,再乘上y/t的因数
每次要找到,从1乘到x/t的最小次数, 这一步用约数dp
*/
vector<vector<int>> g(N+10);//每个数的约数
void init(){
for(int i=1;i<=N;i++){
for(int j=i;j<=N;j+=i){
g[j].push_back(i);
}
}
}
void solve(){
int x,y,k;
cin>>x>>y>>k;
if(k==1){
if(x==y) cout<<0<<endl;
else cout<<-1<<endl;
return;
}
int t=__gcd(x,y);
x/=t;
y/=t;
auto work=[&](int val)-> int {
int n=g[val].size();
vector<int> f(n,inf);
f[0]=0;
for(int i=0;i<n;i++){
if(f[i]==inf) continue;
for(int j=i+1;j<n;j++){
if(g[val][j]%g[val][i]==0 && g[val][j]/g[val][i]<=k){
f[j]=min(f[j],f[i]+1);
}
if(g[val][j]/g[val][i]>k) break;
}
}
return f[n-1];
};
int ans1=work(x);
int ans2=work(y);
if(ans1+ans2>inf/2){
cout<<-1<<endl;
}
else{
cout<<ans1+ans2<<endl;
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
init();
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}

浙公网安备 33010602011771号