icpc刷题记录
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了icpc刷题记录相关的知识,希望对你有一定的参考价值。
E. Exam Results
尺取法,理清思路很重要。
1.将各个人的分数从大到小排序。将每个值作为本次枚举的大值,往后枚举看都多少个满足要求的值。
2.枚举的大值条件是:必须大于等于每个人获取最低分的最大值。
#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
using namespace std;
const int N = 3e6+100;
int n,p,vis[N];
struct node
int id,val;
e[N];
bool cmp(node e1,node e2)
return e1.val>e2.val;
signed main()
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T;cin>>T;
int g=0;
while(T--)
g++;
cin>>n>>p;
for(int i=0;i<=n+5;i++)
vis[i]=0,e[i].val=0,e[i].id=0;
int mx=0;
for(int i=1;i<=n;i++)
int a,b;cin>>a>>b;
e[i]=i,a;e[n+i]=i,b;
mx=max(mx,b);
n*=2;
sort(e+1,e+n+1,cmp);
int t=0,h=0,cnt=0,ans=0;
for(int i=1;i<=n;i++)
if(e[i].val<mx) break;
while(t<n&&e[t+1].val*100>=e[i].val*p)
t++;
vis[e[t].id]++;
if(vis[e[t].id]==1) cnt++;
ans=max(ans,cnt);
vis[e[i].id]--;
if(!vis[e[i].id]) cnt--;
cout<<"Case #"<<g<<": "<<ans<<endl;
return 0;
L. Clock Master
树上dp,求三个块内的点两两互相到达的距离。
#include <bits/stdc++.h>
#define int long long
#define endl '\\n'
using namespace std;
const int N=7e5+5;
int n,sz[4][N],cnt[5];
double ans;
vector<pair<int,int>>e[N];
void dfs1(int u,int fa)
for(auto x:e[u])
int v=x.first,w=x.second;
if(v==fa) continue;
dfs1(v,u);
for(int i=1;i<=3;i++)
sz[i][u]+=sz[i][v];
void dfs2(int u,int fa)
for(auto x:e[u])
int v=x.first,w=x.second;
if(v==fa) continue;
dfs2(v,u);
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(i==j) continue;
ans+=(sz[j][v]*1.0*(sz[i][1]-sz[i][v])*w/cnt[i]/cnt[j]/2);
void solve()
cin>>n;
for(int i=1;i<n;i++)
int u,v,w;cin>>u>>v>>w;
e[u].push_back(v,w);
e[v].push_back(u,w);
for(int i=1;i<=3;i++)
cin>>cnt[i];
for(int j=1;j<=cnt[i];j++)
int x;cin>>x;
sz[i][x]++;
dfs1(1,0);
dfs2(1,0);
cout<<fixed<<setprecision(9)<<ans<<endl;
signed main()
// int T;cin>>T;
// while(T--)
solve();
return 0;
Problem E
The League of Sequence Designers
思路:前n-2个数为0,后面2个未知数x,y,推公式得到的系数为L-1,L
直接转化为扩欧问题,找到一个y为负的一组解即可
#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
using namespace std;
const int inf=1e18;
const int N =2e6+6;
int k,L,p;
int ex_gcd(int a,int b,int &x,int &y)
if(b==0)
x=1,y=0;return a;
int gcd=ex_gcd(b,a%b,y,x);
y-=a/b*x;
return gcd;
int Cal(int a,int b,int c)
int x,y;
int gcd=ex_gcd(a,b,x,y);
if(c%gcd) return -1;
x*=c/gcd;
b/=gcd;
if(b<0) b=-b;
int ans=x%b;
if(ans<=0) ans+=b;
for(int i=ans;;i+=b)
int g=k-(L-1)*i;
if(g<0&&g%b==0)
p=g/b;
return i;
return ans;
void solve()
cin>>k>>L;
if(L>=2000)
cout<<-1<<endl;return;
int x=Cal(L-1,L,k);
cout<<L<<endl;
for(int i=1;i<=L-2;i++)
cout<<0<<" ";
cout<<p<<" "<<x<<endl;
signed main()
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)
solve();
return 0;
G. Greatest Common Divisor
好多特判啊,这题!!! 麻了
注意点:
1.对于一个数来说,若不为1,则不需要进行进行加1操作,直接输出0;若正好是1个1,那么只需要加1即可。
2.开始讨论d的取值:
若差分后n-1项最大公约数为1,说明没有解,输出-1;
若为0,说明后n-1项都为0,说明数组中所有的数都相同,又回到是否为1的讨论。
3.之后要解决的问题:数组第一项x,后n-1的最大公约数d,对x进行加1的操作,使得gcd(x,d)不为1,暴力求出需要几次操作。
#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
#define ios ios::sync_with_stdio(false)
#pragma-GCC-optimize("-Ofast");
using namespace std;
const int N =1e6+5;
const int inf=1e18;
const int mod=1e9+7;
const double eps=1e-8;
int n,a[N],b[N],cnt;
void solve()
cnt++;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(n==1&&a[1]!=1)
cout<<"Case "<<cnt<<": "<<0<<endl;return;
else if(n==1&&a[1]==1)
cout<<"Case "<<cnt<<": "<<1<<endl;return;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) b[i]=a[i]-a[i-1];
int d=0;
for(int i=2;i<=n;i++)
d=__gcd(b[i],d);
if(d==1)
cout<<"Case "<<cnt<<": "<<-1<<endl;
return;
else if(d==0)
if(a[1]==1)
cout<<"Case "<<cnt<<": "<<1<<endl;
else
cout<<"Case "<<cnt<<": "<<0<<endl;
return;
int x=a[1];
if(__gcd(x,d)!=1)
cout<<"Case "<<cnt<<": "<<0<<endl;return;
vector<int>e;
for(int i=1;i*i<=d;i++)
if(d%i==0)
e.push_back(i);
if(d%i==0&&d/i!=i)
e.push_back(d/i);
int ans=inf;
//cout<<x<<" "<<d<<endl;
for(int y:e)
if(y==1) continue;
int g=(x/y+1)*y-x;
//cout<<y<<" "<<g<<endl;
ans=min(ans,g);
cout<<"Case "<<cnt<<": "<<ans<<endl;return;
signed main()
ios;
int T;cin>>T;
while(T--)
solve();
return 0;
Average distance
将一个树中任意两个点权值累加。
#include <bits/stdc++.h>
#define int long long
#define endl '\\n'
using namespace std;
const int N=7e5+5;
vector<pair<int,int>>e[N];
int n,sz[N];
double dp[N];
void dfs(int u,int fa)
sz[u]=1;
for(auto x:e[u])
int v=x.first,w=x.second;
if(v==fa) continue;
dfs(v,u);
sz[u]+=sz[v];
dp[u]+=(dp[v]+(sz[v]*1.0*(n-sz[v])*w));
void solve()
cin>>n;
for(int i=0;i<=n+5;i++) e[i].clear(),dp[i]=0,sz[i]=0;
for(int i=1;i<n;i++)
int u,v,w;cin>>u>>v>>w;
e[u].push_back(v,w);
e[v].push_back(u,w);
dfs(0,-1);
int bas以上是关于icpc刷题记录的主要内容,如果未能解决你的问题,请参考以下文章