H. Horizon Scanning
- 这道题答案有单调性不假,可是也不是有单调性就一定要二分的吧?貌似直接取最小值就好了呀……
#include <bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
struct t1
{double x,y;double r;
}t[400005];
bool cmp(t1 a,t1 b)
{return a.r<b.r;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){int n,k;cin>>n>>k;for(int i=1;i<=n;i++){cin>>t[i].x>>t[i].y;if(t[i].x>=0&&t[i].y>0){t[i].r=pi/2-(atan(t[i].x/t[i].y));}else if(t[i].x<0&&t[i].y>=0){t[i].r=pi-atan(-t[i].y/t[i].x);}else if(t[i].x<=0&&t[i].y<0){t[i].r=pi+(pi/2-atan(t[i].x/t[i].y));}else if(t[i].x>0&&t[i].y<=0){t[i].r=2*pi-atan(-t[i].y/t[i].x);}}sort(t+1,t+n+1,cmp);for(int i=1;i<n;i++){t[i+n]=t[i];t[i+n].r+=2*pi;}double l=0,r=2*pi;int eps=100;while(eps--){double mid=(l+r)/2;bool f=true;for(int i=1;i<=n;i++){auto check=[i,mid](t1 x){return x.r-t[i].r<mid;};int p=partition_point(t+i,t+n+i,check)-1-t;if(p-i<k){f=false;break;}}if(f==true){r=mid;}else{l=mid;}}cout<<fixed<<setprecision(10)<<l<<"\n";}return 0;
}
L. Last Chance: Threads of Despair
- and each of his minions can attack any one minion from the opposing faction at most once. 是指每个己方势力总共只能攻击一次,而不是每个己方势力都可以攻击每个敌方势力各一次
- 引理:必然存在一种方案使得我方先进行所有攻击操作,此后不断发生爆炸直到对方所有单位清空
- 证明:如果一个操作方案中,在某次攻击之前发生过爆炸,那么我们将此次攻击移动到所有攻击之前,效果不变,同时也不会导致原本的其他操作失效
- 模拟一次攻击操作太麻烦了,有没有什么更简便的做法呢?当然有了,把己方健康值-1和敌方健康值-1分离。先把己方的攻击次数统一提取出来,再贪心地分配给敌方就好啦。
#include <bits/stdc++.h>
using namespace std;
int a[500005],b[500005],n,m;
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){cin>>n>>m;int tot=0;for(int i=1;i<=n;i++){cin>>a[i];tot+=(a[i]>1);}sort(a+1,a+n+1);tot+=(a[1]==1);for(int i=1;i<=m;i++){cin>>b[i];}sort(b+1,b+m+1);int p=0,q=0,cur=0;while(q<m){while(p<n&&a[p+1]-1<=cur){p++;cur++;}if(b[q+1]>cur){tot-=(b[q+1]-cur);if(tot<0){break;}}q++;cur++;}q==m? cout<<"Yes\n":cout<<"No\n";}return 0;
}
G. GCD
- 一开始没什么思路。午休的时候躺在床上想,
你精通GCD和各种动态规划,居然想不到做法,而且榜单上还能有200多个队伍过题,会不会答案是有限的,直接搜索就好了呢?一试,真的通过了!看来,根据榜单上的过题人数感受题目大致的做法,是一项远被之前的你低估的能力。大家其实也都不太会猜,你看学校的主力队伍交了快10次才在比赛即将结束的时候通过呢
#include <bits/stdc++.h>
using namespace std;
int ans,cur;
void solve(long long a,long long b)
{if(cur>=ans){return;}if(a==0){ans=min(ans,cur+1);return; }if(b%a==0){ans=min(ans,cur+2);return;}int g=__gcd(a,b);cur++;solve(a-g,b);solve(a,b-g);cur--;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){long long a,b;cin>>a>>b;ans=20;cur=0;solve(a,b);cout<<ans<<"\n";}return 0;
}
C. Coin
- 倒序思考+数论分块,很轻松就解决啦~有什么难的呢?
#include <bits/stdc++.h>
using namespace std;
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){long long n,k;cin>>n>>k;long long cur=k-1;if(cur>=n){cout<<n<<"\n";continue;}else{while(cur+cur/(k-1)+(cur%(k-1)>0)<=n){if(cur%(k-1)&&cur/(k-1)==(cur+cur/(k-1)+1)/(k-1)){long long cnt=min(n-cur,k-1-cur%(k-1))/(cur/(k-1)+1);cur=cur+cnt*(cur/(k-1))+cnt;continue;}cur=cur+cur/(k-1)+(cur%(k-1)>0);}cout<<cur<<"\n";}}return 0;
}
- 原来所谓的金银牌分界题,也不过是个简简单单的高斯消元罢了~
#include <bits/stdc++.h>
using namespace std;
vector<int>a[305];
int c[305*305][305],tmp[305*305][305];
int n,m,k;
int q[305];
bool Gauss()
{memcpy(tmp,c,sizeof(tmp));for(int i=1;i<=n;i++){for(int j=i;j<=m;j++){if(c[j][i]>0){swap(c[i],c[j]);break;}}if(!c[i][i]){return false;}q[i]=c[i][n+2];for(int j=1;j<=m;j++){if(i!=j&&c[j][i]){for(int k=1;k<=n;k++){c[j][k]^=c[i][k];}}}}memcpy(c,tmp,sizeof(c));return true;
}
void Gauss(int n)
{for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i!=j&&c[j][i]){for(int k=1;k<=n+1;k++){c[j][k]^=c[i][k];}}}}cout<<"!";for(int i=2;i<=n;i++){cout<<" "<<c[i][n+1];}cout<<endl;
}
int s[305];
void dfs(int n1,int dep,int fa)
{s[dep]=n1;if(dep==k){m++;c[m][0]=s[0];for(int i=0;i<=k;i++){c[m][s[i]]=1;}c[m][n+1]=s[k];c[m][n+2]=m;return;}for(int i=0;i<a[n1].size();i++){if(a[n1][i]!=fa){dfs(a[n1][i],dep+1,n1);}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cin>>n>>k;for(int i=1;i<n;i++){int u,v;cin>>u>>v;a[u].push_back(v);a[v].push_back(u);}m=1;c[1][1]=1;for(int i=1;i<=n;i++){dfs(i,0,0);}if(Gauss()){cout<<"YES"<<endl;cout<<"? "<<n-1;for(int i=2;i<=n;i++){cout<<" "<<c[q[i]][0]<<" "<<c[q[i]][n+1];}cout<<endl;for(int i=2;i<=n;i++){int w;cin>>w;c[q[i]][n+1]=w;memcpy(tmp[i],c[q[i]],sizeof(tmp[i]));}memcpy(c,tmp,sizeof(c));Gauss(n);}else{cout<<"NO"<<endl;}return 0;
}