补题若干(二)
[https://www.luogu.com.cn/problem/AT_abc427_e](暴力+STL)
题意:
给出二维矩阵:T在的位置以及垃圾#在的位置,每次可以使所有#向上/下/左/右移动一次,求使得垃圾不到T而全部被移除的最小操作次数
思路:
用一个set
int n,m;
queue<pair<set<pii>,int>>q;
pii sx;
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
map<set<pii>,int>vis;
void solve(){
cin>>n>>m;
set<pii>st;
rep(i,1,n){
rep(j,1,m){
char k;cin>>k;
if(k=='#')st.insert({i,j});
else if(k=='T')sx={i,j};
}
}
q.push({st,0});
while(q.size()){
auto[Set,step]=q.front();q.pop();
if(vis.count(Set))continue;
vis[Set]=1;
if(Set.size()==0){
cout<<step<<endl;return;
}
for(int i=0;i<4;i++){
set<pii>newset;
int ok=1;
for(auto[x,y]:Set){
int nx=x+dx[i],ny=y+dy[i];
if((pii){nx,ny}==sx){
ok=0;break;
}
if(nx<1||nx>n||ny<1||ny>m)continue;
newset.insert({nx,ny});
}
if(ok)q.push({newset,step+1});
}
}
cout<<-1<<endl;
}
(https://www.luogu.com.cn/problem/AT_abc424_e)[优先队列+暴力]
题意:
\(n\)个树枝,进行\(k\)次的将最长的树枝长度减半的操作,求操作后第\(x\)长的树枝长度
思路:
竟能优先队列模拟:存一个pair,分别表示这个数和这个数的出现次数,模拟即可
时间复杂度O(nlogklogn)
int n,k,x;
void solve(){
cin>>n>>k>>x;
priority_queue<pair<double,int>>pq;
rep(i,1,n){
int x;cin>>x;
pq.push({x*1.0,1});
}
while(k>0){
auto[u,cnt]=pq.top();pq.pop();
if(k>=cnt){
pq.push({u/2,cnt*2});
k-=cnt;
}else{
pq.push({u/2,k*2});
pq.push({u,cnt-k});
k=0;
}
}
while(pq.size()){
auto[u,cnt]=pq.top();
if(x>cnt){
pq.pop();x-=cnt;
}else{
cout<<fixed<<setprecision(18)<<u<<endl;
return;
}
}
}
(https://atcoder.jp/contests/abc422/tasks/abc422_e)[随机化]
题意:
给定\(n\)个点的坐标,求一条能通过\((n+1)/2\)个点的直线方程
思路:
随机取一个点,在这条直线上的概率为\(1/2\)
那么取两个点确定一条直线,check一下就可以了
#define int __int128
#define gc getchar()
#define cin(a) a=read()
int read(){
int x=0;bool fl=0;char s=gc;
while(!isdigit(s)){if(s=='-')fl=1;s=gc;} // 处理符号位
while(isdigit(s))x=(x<<1)+(x<<3)+s-'0',s=gc; // 计算数值,相当于x = x*10 + (s-'0')
return fl?-x:x;
}
void Print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x/10) Print(x/10); // 递归输出高位
putchar(x%10+'0'); // 输出当前位
}
int n;
//ax1+by1+c=0
//ax2+by2+c=0
//a(x1-x2) = -b(y1-y2)
//b = (x1-x2)/(y2-y1)a
//ax1+(x1-x2)*y1/(y2-y1)*a+c=0
void solve(){
cin(n);
vector<pii>a(n+1);
rep(i,1,n){
cin(a[i].fi);
cin(a[i].se);
}
for(int _=1;_<=1e2;_++){
int i=rnd()%n+1;
int j=rnd()%n+1;
while(i==j)j=rnd()%n+1;
int x=a[i].fi,y=a[i].se,xx=a[j].fi,yy=a[j].se;
int A = (y-yy);
int B = (xx-x);
int C = (yy*x-xx*y);
int g=__gcd(A,__gcd(B,C));
A/=g;
B/=g;
C/=g;
int cnt=0;
for(int __=1;__<=n;__++){
int X = a[__].fi,Y=a[__].se;
if(A*X+B*Y+C==0)cnt++;
}
if(cnt>=(n+1)/2){
cout<<"Yes"<<endl;
Print(A);
putchar(' ');
Print(B);
putchar(' ');
Print(C);
return;
}
}
cout<<"No"<<endl;
}

浙公网安备 33010602011771号