终于搞完了!!!!!
dalao们都说水,但蒟蒻表示挺难的;
有件事很开心;
其中四道题是自己独立AC的;
一道想到正解(Day 2 T3),但不会卡常;
至于还有一道……一点思路也没有(Day 2 T2);
T1:
题目:
https://www.luogu.org/problem/show?pid=2615
模拟,日常签到题,注意坐标具有传递性;
#include
#include
#include
#include
using namespace std;
int ma[2001][2001],n,tot=1;
void solve()
{
scanf("%d",&n);
ma[1][n/2+1]=tot;
int x=1,y=n/2+1;
while(totif(x==1 && y!=n) x=n,y++;
else if(x!=1 && y==n) y=1,x--;
else if(x==1 && y==n) x++;
else if(x!=1 && y!=n)
{
if(!ma[x-1][y+1]) x--,y++;
else x++;
}
ma[x][y]=tot;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) cout<" ";
cout<int main()
{
solve();
return 0;
}
T2:
题目:
https://www.luogu.org/problem/show?pid=2661
tarjan或dfs;
比较裸的求最小环;
#include
#include
#include
#include
#include
using namespace std;
stack<int>s;
const int MAXN=200001;
int dfn[MAXN],low[MAXN],fst[MAXN],nxt[MAXN],scc[MAXN];
int n,tot,tim,cnt,f,ans=324252;
struct hh
{
int from,to;
}map[MAXN];
void build(int f,int t)
{
tot++;
map[tot]=(hh){f,t};
nxt[tot]=fst[f];
fst[f]=tot;
return;
}
void tarjan(int x)
{
low[x]=dfn[x]=++tim;
s.push(x);
for(int i=fst[x];i!=-1;i=nxt[i])
{
int v=map[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(!scc[v]) low[x]=min(low[x],dfn[v]);
}
if(dfn[x]==low[x])
{
cnt++;
int num=0;
while(true)
{
int u=s.top();
s.pop();
num++,scc[x]=cnt;
if(u==x)
{
if(num>1) ans=min(num,ans);
break;
}
}
}
return;
}
void solve()
{
memset(fst,-1,sizeof(fst));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&f);
build(i,f);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
cout<return;
}
int main()
{
solve();
return 0;
}
T3:
题目:
https://www.luogu.org/problem/show?pid=2668
注意答案的更新;
挺简单的一道题,但是细节处理较多;
题解:http://blog.csdn.net/qq_36312502/article/details/77970178;
爆搜;
#include
#include
#include
#include
using namespace std;
int t,n,cnt[10001],ans,num;
void init()
{
memset(cnt,0,sizeof(cnt));
ans=n;
return;
}
int cnt1,cnt2,cnt3,cnt4,cnt5;
void dfs(int x)
{
cnt1=cnt2=cnt3=cnt4=cnt5=0;
for(int i=1;i<=14;i++)
{
if(cnt[i]==1) cnt1++;
else if(cnt[i]==2) cnt2++;
}
for(int i=1;i<=14;i++)//三带一 三带二
{
if(cnt[i]==3)
{
cnt3++;
if(cnt1>=1) cnt1--;
else if(cnt2>=1) cnt2--;
}
}
for(int i=1;i<=14;i++) //四带二
{
if(cnt[i]==4)
{
cnt4++;
if(cnt1>=2) cnt1-=2;
else if(cnt2>=2) cnt2-=2;
else if(cnt2>=1) cnt2--;//四带一个对子也可以;
}
}
ans=min(ans,x+cnt1+cnt2+cnt3+cnt4);
for(int i=1;i<=8;i++) //单顺子
{
int j;
for(j=i;j<=12;j++)
{
if(cnt[j]<1) break;
cnt[j]--;
if(j-i>=4) dfs(x+1);
}
for(int k=i;k<=j-1;k++) cnt[k]++;
}
for(int i=1;i<=10;i++) // 双顺子
{
int j;
for(j=i;j<=12;j++)
{
if(cnt[j]<2) break;
cnt[j]-=2;
if(j-i>=2) dfs(x+1);
}
for(int k=i;k<=j-1;k++) cnt[k]+=2;
}
for(int i=1;i<=11;i++) // 三顺子
{
int j;
for(j=i;j<=12;j++)
{
if(cnt[j]<3) break;
cnt[j]-=3;
if(j-i>=1) dfs(x+1);
}
for(int k=i;k<=j-1;k++) cnt[k]+=3;
}
return;
}
void solve()
{
init();
int x,y;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
if(x==0) cnt[14]++;
else if(x==1) cnt[12]++;
else if(x==2) cnt[13]++;
else cnt[x-2]++;
}
dfs(0);
cout<int main()
{
scanf("%d%d",&t,&n);
int hh=t;
while(hh--) solve();
return 0;
}
T1:
题目:
https://www.luogu.org/problem/show?pid=2678
二分;
题解:
http://blog.csdn.net/qq_36312502/article/details/77869900
#include
#include
#include
#include
using namespace std;
int r,l=1,L,n,m,ans,last;
int a[100001];
bool check(int x)
{
int ans=0,last=0;
for(int i=1;i<=n+1;i++)
{
if(a[i]-lastelse last=a[i];
}
if(ans>m) return 1;
else return 0;
}
void solve()
{
cin>>L>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
r=a[n+1]=L;
while(r-l>1)
{
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid;
}
if(!check(r)) l=r;
cout<int main()
{
solve();
return 0;
}
T2:
题目:
https://www.luogu.org/problem/show?pid=2679
DP,难;
题解:
http://blog.csdn.net/qq_36312502/article/details/78127290
#include
#include
#include
#include
using namespace std;
const int mod=1000000007;
int dp[3][301][301][3],cnt,now,pre=1,n,m,t;
char s1[1021],s2[1021];
void solve()
{
cin>>n>>m>>t;
scanf("%s%s",s1+1,s2+1);
for(int i=1;i<=n;i++)
{
swap(now,pre);
dp[now][1][1][0]=cnt;
if(s1[i]==s2[1]) dp[now][1][1][1]=1,cnt++;
for(int j=2;j<=m;j++)
{
for(int k=1;k<=t;k++)
{
if(s1[i]==s2[j])
dp[now][j][k][1]=((dp[pre][j-1][k-1][0]+dp[pre][j-1][k-1][1])%mod+dp[pre][j-1][k][1])%mod;
dp[now][j][k][0]=(dp[pre][j][k][0]+dp[pre][j][k][1])%mod;
}
}
for(int j=1;j<=m;j++)
for(int k=1;k<=t;k++)
dp[pre][j][k][1]=dp[pre][j][k][0]=0;
}
cout<<(dp[now][m][t][1]+dp[now][m][t][0])%mod;
return;
}
int main()
{
solve();
return 0;
}
T3:
题目:
https://www.luogu.org/problem/show?pid=2680
lca+树上差分+二分;
题解:
http://blog.csdn.net/qq_36312502/article/details/78121945
#include
#include
#include
#include
using namespace std;
const int MAXN=600008;
int fst[MAXN],nxt[MAXN],num[MAXN],tmp[MAXN],dis[MAXN];
int deep[MAXN],top[MAXN],sz[MAXN],fa[MAXN],son[MAXN],dfn[MAXN];
int tot,n,m,l=-1,r,totp;
struct hh {int from,to,cost;}ss[MAXN];
struct edge {int from,to,lca,dis;}ma[MAXN];
void build(int f,int t,int c)
{
tot++;
ss[tot]=(hh){f,t,c};
nxt[tot]=fst[f];
fst[f]=tot;
return;
}
void dfs1(int x,int f,int c)
{
dfn[++totp]=x;
fa[x]=f,deep[x]=deep[f]+1,sz[x]=1,dis[x]=c;
for(int i=fst[x];i;i=nxt[i])
{
int v=ss[i].to;
if(v==f) continue;
num[v]=ss[i].cost;
dfs1(v,x,c+ss[i].cost),sz[x]+=sz[v];
if(!son[x] || sz[son[x]]return;
}
void dfs2(int x,int st)
{
top[x]=st;
if(!son[x]) return;
dfs2(son[x],st);
for(int i=fst[x];i;i=nxt[i])
{
int v=ss[i].to;
if(v==fa[x] || v==son[x]) continue;
dfs2(v,v);
}
return;
}
int lca(int x,int y)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(deep[fx]return deep[x]bool check(int ans)
{
int lim=-1,cnt=0;
memset(tmp,0,sizeof(tmp));
for(int i=1;i<=m;i++)
{
if(ma[i].dis>ans)
{
tmp[ma[i].from]++,tmp[ma[i].to]++;
tmp[ma[i].lca]-=2;
lim=max(lim,ma[i].dis-ans);
cnt++;
}
}
if(!cnt) return true;
for(int i=n;i>=1;i--) tmp[fa[dfn[i]]]+=tmp[dfn[i]];
for(int i=2;i<=n;i++)
if(num[i]>=lim && tmp[i]==cnt) return true;
return false;
}
void solve()
{
int x,y,z;
scanf("%d%d",&n,&m);
for(int i=1;iscanf("%d%d%d",&x,&y,&z);
build(x,y,z),build(y,x,z);
r+=z;
}
dfs1(1,0,0),dfs2(1,1);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
ma[i]=(edge){x,y,lca(x,y),dis[x]+dis[y]-2*dis[lca(x,y)]};
}
while(r-l>1)
{
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid;
}
cout<return;
}
int main()
{
solve();
return 0;
}