第一次周赛补题(接上周部分)
#include<bits/stdc++.h>
using namespace std;
int m,n,L,R,mid;
int N[10086110];
int check(int V)//判断敌人的行进距离。若敌人的行进距离<敌人与小明的距离则能击杀。
{
int num=1,TEM=0;
if(N[1]>m+TEM)TEM+=N[1]-m;//判断第一个敌人是否在射程内
for(int i=2;i<=n;i++)
{
TEM+=V;
if(TEM>N[i])
{
return 0;
break;
}
else num++;
}
//cout<<"num="<<num<<endl;
if(num>=n)return 1 ;//判断能否全部击毙
else return 0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>N[i];
sort(N+1,N+1+n);
L=0,R=N[n]+1;
while(L+1!=R)
{
mid=(L+R)/2;
if(check(mid))L=mid;
else R=mid;
//cout<<"L="<<L<<" "<<"R="<<R<<endl;
}
if(check(R))cout<<R;
else cout<<L;
}
#include <bits/stdc++.h>
using namespace std;
struct j
{
int value,tail,head,flag;
}L[100861];
int v,t,h,flag,o;
int head,n,k,tem1,tem2;
int main()
{
cin>>head>>n>>k;
for(int i=0;i<n;i++)
{
cin>>flag>>v>>t;
L[flag].value=v,L[flag].tail=t,L[i].flag=flag;
L[L[flag].tail].head=L[flag].tail;
}
L[head].head=head;
vector<j>S;
for(int i=head;i!=-1;i=L[i].tail)
{
S.push_back(L[i]);
o++;//取得有效节点数
}
n=min(n,o);
for(int i=0;i<n/k;i++)reverse(S.begin()+i*k,S.begin()+(i+1)*k);反转链表
int l=S.size();
for(int i=0;i<l;i++)
{
if(i<=l-2)cout<<setw(5)<<setfill('0')<<S[i].head<<" "<<S[i].value<<" "<<setw(5)<<setfill('0')<<S[i+1].head<<endl;
else cout<<setw(5)<<setfill('0')<<S[i].head<<" "<<S[i].value<<' '<<"-1";
}
}
/*求导,通过求根公式求得导数两根,然后根据aX^2+bX+c=0中a的正负得到增减区间再进行二分*/
#include<bits/stdc++.h>
using namespace std;
double a,b,c,d,p,q,mid,L,R,L1,R1,L2,R2,ans1,s2,s3,s1,x1,x2,A[3];
vector<double>V;
double check(double I,double a,double b,double c,double d,double flag)
{
if(flag>0)//导数大于0,增函数
{
if(a*I*I*I+b*I*I+c*I+d<0)return 1;
else return 0;
}
else
{
if(a*I*I*I+b*I*I+c*I+d<=0)return 0;
else return 1;
}
}
void erfen(double L,double R,double flag)
{
while(fabs(L-R)>1e-7)
{
mid=(L+R)/2;
if(check(mid,a,b,c,d,flag))L=mid;
else R=mid;
}
ans1=(R+L)/2;
V.push_back(ans1);
}
double check1(double I,double a,double b,double c,double d)
{
return 3*a*I*I+b*I+c;
}
void check1(double a,double b,double c)
{
double A=3*a,B=2*b,C=c,A1,B1;
A1=((-B-sqrt(B*B-4*A*C))/(2*A));
B1=((-B+sqrt(B*B-4*A*C))/(2*A));
x1=min(A1,B1);//cout<<x1<<endl;
x2=max(A1,B1);//cout<<x2<<endl;//(p,x1)(x1,x2)(x2,q)
if(a>0)s1=1,s2=-1,s3=1;
else s1=-1,s2=1,s3=-1;
}
int main()
{
int t;
cin>>t;
while(t>0)
{
cin>>a>>b>>c>>d>>p>>q;
check1(a,b,c);
//cout<<"P="<<p<<" "<<"x1="<<x1<<" "<<"x2="<<x2<<" "<<"Q="<<q<<endl;
L=p,R=x1;
erfen(L,R,s1);
L=x1,R=x2;
erfen(L,R,s2);
L=x2,R=q;
erfen(L,R,s3);
t--;
for(int i=0;i<3;i++)
{
cout<<fixed<<setprecision(6)<<V[i];
if(i!=2)cout<<' ';
}
cout<<endl;
V.clear();
}
}
#include<bits/stdc++.h>
using namespace std;
vector< int >V[1008];
int m,n,a,b,Begin,End,ans,sum;
bool vis[1008];
int ANS[1008];
void dfs (int Begin)
{
if(Begin==End)//到达终点
{
sum++;//路径总数
for(int i=1;i<=n;i++)
{
if(vis[i])ANS[i]++;
}
return;
}
for(int i=0;i<V[Begin].size();i++)
{
if(!vis[V[Begin][i]])
{
vis[V[Begin][i]]=1;
dfs(V[Begin][i]);
vis[V[Begin][i]]=0;
}
}
return;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>a>>b;//双向
V[a].push_back(b);//a->b
V[b].push_back(a);//b->a
}
cin>>Begin>>End;
vis[Begin]=1;//起点标记为已走过
dfs(Begin);
for(int i=1;i<=n;i++)if(ANS[i]==sum)ans++;
if(ans==0)cout<<"-1";
else cout<<ans-2;//起点终点一定会走过
}
#include<bits/stdc++.h>
using namespace std;
int N,M,n,start,k;
vector<int >V[100100];
int ans[100100];
bool vis[100100];
void dfs(int step)//先是正向dfs未得出正确答案
{
ans[start]=max(ans[start],step);// 山穷水尽了
for(int i=0;i<V[step].size();i++)
{
if(vis[V[step][i]]==0)
{
vis[V[step][i]]=1;
dfs(V[step][i]);
vis[V[step][i]]=0;
k++;
}
if(k>10000)break;
}
return;
}
void redfs(int step)//从终点往回走
{
vis[step]=1;
ans[step]=max(ans[step],start);
//cout<<"step="<<step<<" "<<"ans[step]="<<ans[step]<<endl;
for(int i=0;i<V[step].size();i++)
{
if(vis[V[step][i]]==0)
{
redfs(V[step][i]);//不用回溯,回溯会超时
}
}
return;
}
int main()
{
cin>>N>>M;
for(int i=1;i<=M;i++)
{
int a,b;
cin>>a>>b;
V[b].push_back(a);//b->a(单向)
}
for(int i=N;i>=0;i--)
{
start=i;
if(!vis[start])redfs(start);//
//cout<<endl;
}
for(int i=1;i<=N;i++)
{
cout<<ans[i];
if(i!=N)cout<<' ';
}
}
参考文献:381 二分图判定 染色法_哔哩哔哩_bilibili
//用了染色法判断是否存在节点个数为奇数的环
#include<bits/stdc++.h>
#include <cstring>
using namespace std;
struct edge
{
int to,next,w;
}edge[20020];
int cnt,head[20020];
void add(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}//什么链式前向星
int color[10010];
int ans[3],Ans;
int tem1,tem2,n,m;
bool dfs(int u,int Color)
{
color[u]=Color;//先给当前点位染色
ans[Color]++;//染了"Color"色的节点个数++
for(int i =head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;//下一个点位
if(color[v]==0)//未染色
{
if(dfs(v,3-Color))return true;//判断相邻点位是否存在奇环
}
else if(color[v]==Color)return true;//奇环
}
return 0;
}
int main()
{
memset(head,-1, sizeof(head));
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>tem1>>tem2;
add(tem1,tem2);
add(tem2,tem1);
}
for(int i=1;i<=n;i++)
{
if(color[i]==0)
{
ans[1]=ans[2]=0;//先将两种颜色的节点数都计为0
if(dfs(i,1))
{
cout<<"Impossible"<<endl;//有奇环输出"Impossible"
return 0;
}
Ans+=min(ans[1],ans[2]);//ans[1]是染上"1"色的节点个数,ans[2]是染上"2"色的节点个数
}
}
cout<<Ans;
}