L2-005 集合相似度
find函数,Nt用集合关系求
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n,k;
set<int>s[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int cnt;
cin>>cnt;
for(int j=1;j<=cnt;j++)
{
int x;
cin>>x;
s[i].insert(x);
}
}
cin>>k;
while(k--)
{
int a,b;
cin>>a>>b;
int Nc=0,Nt=0;
for(auto i:s[a])
if(s[b].find(i)!=s[b].end())
Nc++;
Nt=s[a].size()+s[b].size()-Nc;
printf("%.2f%\n",100.0*Nc/Nt);
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
// ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-008 最长对称子串
思路:f[i]表示以第i个字符结尾的最长对称子串的长度。
注意初始化:若s[i]==s[i-1] ,f[i]=f[i-1]+1;否则f[i]=1
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
string s;
int f[N];
void solve()
{
getline(cin,s);
s='?'+s;
int n=s.length();
for(int i=1;i<n;i++)
{
if(s[i]==s[i-1]) f[i]=f[i-1]+1;
else f[i]=1;
}
for(int i=1;i<n;i++)
{
if(i-f[i-1]-1>=1&&s[i-f[i-1]-1]==s[i]) f[i]=max(f[i],f[i-1]+2);
else f[i]=max(f[i],1);
}
int ans=1;
for(int i=1;i<n;i++)
ans=max(ans,f[i]);
cout<<ans<<'\n';
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-010 排座位
题意:
思路:二维数组g表示两者之间的朋友和敌对关系。将存在朋友的关系的合并在一块,做一个并查集。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=110;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m,k;
int fa[2*N],g[N][N];
int find(int x)
{
return fa[x]==x? x:fa[x]=find(fa[x]);
}
void merge(int a,int b)
{
fa[find(a)]=find(b);
}
void solve()
{
cin>>n>>m>>k;
for(int i=0;i<N;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
int a,b,c;
cin>>a>>b>>c;
if(c==1)
{
g[a][b]=g[b][a]=1;
merge(a,b);
}
else
{
g[a][b]=g[b][a]=-1;
}
}
while(k--)
{
int a,b;
cin>>a>>b;
if(g[a][b]==1) puts("No problem");
else if(g[a][b]==0) puts("OK");
else
{
if(find(a)==find(b)) puts("OK but...");
else puts("No way");
}
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-011 玩转二叉树
题意:
思路:根据中序遍历和前序遍历还原二叉树,反转后输出答案。
中序遍历:LDR,可以划分出左右子树
前序遍历:DLR,可以找到子树的根。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
struct node{
int l,r;
}tr[N];
int n;
int z[N],q[N];
bool st[N];
map<int,int>pos;
void dfs(int u)
{
st[u]=1;
int p=0;
for(int i=1;i<=n;i++)
if(z[i]==u)
{
p=i;
break;
}
priority_queue<PII,vector<PII>,greater<PII>>L,R;
for(int i=p-1;i>=1;i--)
if(!st[z[i]]) L.push({pos[z[i]],z[i]});
else break;
for(int i=p+1;i<=n;i++)
if(!st[z[i]]) R.push({pos[z[i]],z[i]});
else break;
if(L.size())
{
int t=L.top().second;
tr[u].l=t;
dfs(t);
}
else tr[u].l=-1;
if(R.size())
{
int t=R.top().second;
tr[u].r=t;
dfs(t);
}
else tr[u].r=-1;
}
vector<int>ans;
void get(int u)
{
queue<int>q;
q.push(u);
while(q.size())
{
int t=q.front();q.pop();
ans.push_back(t);
if(tr[t].r!=-1) q.push(tr[t].r);
if(tr[t].l!=-1) q.push(tr[t].l);
}
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>z[i];
for(int i=1;i<=n;i++)
{
cin>>q[i];
pos[q[i]]=i;
}
int root=q[1];
dfs(root);
get(root);
for(int i=0;i<ans.size();i++)
cout<<ans[i]<<" \n"[i==n-1];
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-012 关于堆的判断
题意:
思路:模拟堆,注意up的写法。注意xy可能为负
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m;
int h[N],sz;
void up(int u)
{
while(u/2&&h[u/2]>h[u])
{
swap(h[u/2],h[u]);
u/=2;
}
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
sz++;
h[sz]=x;
up(sz);
}
// for(int i=1;i<=n;i++)
// cout<<i<<' '<<h[i]<<'\n';
getchar();
while(m--)
{
string s;
getline(cin,s);
char c;
int cnt=0;
for(int i=0;i<s.length();i++)
{
if(cnt==3)
{
c=s[i];
break;
}
if(s[i]==' ') cnt++;
}
int x=0;bool f=0;
for(int i=0;i<s.length();i++)
{
if(s[i]==' ') break;
else
{
if(s[i]>='0'&&s[i]<='9') x=x*10+int(s[i]-'0');
else f=1;
}
}
if(f) x*=-1;
if(c=='r')
{
if(h[1]==x) puts("T");
else puts("F");
}
else if(c=='a')
{
cnt=0;
int y=0;
f=0;
for(int i=0;i<s.length();i++)
{
if(cnt==2)
{
if(s[i]=='-') f=1;
else if(s[i]>='0'&&s[i]<='9') y=y*10+int(s[i]-'0');
else break;
}
if(s[i]==' ') cnt++;
}
if(f) y*=-1;
int px=0,py=0;
for(int i=1;i<=sz;i++)
if(h[i]==x)
{
px=i;
break;
}
for(int i=1;i<=sz;i++)
if(h[i]==y)
{
py=i;
break;
}
if(px/2==py/2) puts("T");
else puts("F");
}
else if(c=='p')
{
cnt=0;
int y=0;f=0;
for(int i=0;i<s.length();i++)
{
if(cnt==5)
{
if(s[i]=='-') f=1;
else if(s[i]>='0'&&s[i]<='9') y=y*10+int(s[i]-'0');
else break;
}
if(s[i]==' ') cnt++;
}
if(f) y*=-1;
int px=0,py=0;
for(int i=1;i<=sz;i++)
if(h[i]==x)
{
px=i;
break;
}
for(int i=1;i<=sz;i++)
if(h[i]==y)
{
py=i;
break;
}
if(px==py/2) puts("T");
else puts("F");
}
else
{
cnt=0;
int y=0;f=0;
for(int i=0;i<s.length();i++)
{
if(cnt==5)
{
if(s[i]=='-') f=1;
else if(s[i]>='0'&&s[i]<='9') y=y*10+int(s[i]-'0');
else break;
}
if(s[i]==' ') cnt++;
}
if(f) y*=-1;
int px=0,py=0;
for(int i=1;i<=sz;i++)
if(h[i]==x)
{
px=i;
break;
}
for(int i=1;i<=sz;i++)
if(h[i]==y)
{
py=i;
break;
}
if(px/2==py) puts("T");
else puts("F");
}
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-013 红色警报
题意:
思路:若一个城市失去会影响其他城市的连通性,那么失去后的连通块个数>失去前的连通块个数+1.
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=510;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m,k;
bool g[N][N];
bool st[N];
void bfs(int x)
{
queue<int>q;
q.push(x);
st[x]=1;
while(q.size())
{
int t=q.front();
q.pop();
for(int i=0;i<n;i++)
{
if(g[t][i]&&!st[i])
{
q.push(i);
st[i]=1;
}
}
}
}
int get()
{
for(int i=0;i<n;i++) st[i]=0;
int ret=0;
for(int i=0;i<n;i++)
{
if(!st[i])
{
bfs(i);
ret++;
}
}
return ret;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
g[a][b]=g[b][a]=1;
}
int last=get();
cin>>k;
int cnt=0;
for(int i=1;i<=k;i++)
{
int x;
cin>>x;
cnt++;
for(int j=0;j<n;j++)
g[x][j]=g[j][x]=0;
int cur=get();
if(cur>last+1) printf("Red Alert: City %d is lost!\n",x);
else printf("City %d is lost.\n",x);
if(cnt==n) printf("Game Over.\n");
last=cur;
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-014 列车调度
题意:
思路:因为要递减出站,同时为减少轨道条数,那么同一轨道上的火车从前到后编号一定是递减的。我们只需要关注每条轨道上最后一辆的编号即可。当要入站的编号比所有的都大,那么我们要新开一条轨道;否则我们就对大于要放入的值的轨道的值检索,找出跟其相差最少的一条轨道,把值放进去。
因为当要开新轨道时,新轨道的值一定是最大的。那么每条轨道的编号一定是递增的。我们在检索相差最少的一条轨道时就可以通过二分法来检索。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n,cur;
int a[N];
int tra[N],k;
int search(int x)
{
int l=0,r=k-1;
while(l<r)
{
int mid=l+r>>1;
if(tra[mid]<x) l=mid+1;
else r=mid;
}
return l;
}
void fun(int x)
{
if(tra[k-1]<x) tra[k++]=x;
else tra[search(x)]=x;
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) fun(a[i]);
cout<<k<<'\n';
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-016 愿天下有情人都是失散多年的兄妹
题意:
思路:对于每对查询的a,b,找出a,b五代内的亲人并标记,若有人被标记两次,则No。
注意要保存父母的性别。否则,父母的性别没给出的情况下,查询性别都是默认值,会出错。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
struct node{
int l=-1,r=-1;
char sex;
}tr[N];
int n;
bool check(int a,int b)
{
map<int,int>mp;
mp[a]++,mp[b]++;
if(mp[a]>=2) return 0;
queue<node>q;
q.push(tr[a]);q.push(tr[b]);
for(int i=1;i<=4;i++)
{
queue<node>cur;
while(q.size())
{
node t=q.front();
q.pop();
if(t.l!=-1)
{
cur.push(tr[t.l]),mp[t.l]++;
if(mp[t.l]>=2)
{
return 0;
}
}
if(t.r!=-1)
{
cur.push(tr[t.r]),mp[t.r]++;
if(mp[t.r]>=2)
{
return 0;
}
}
}
q=cur;
}
for(auto [a,b]:mp)
if(b>=2)
{
return 0;
}
return 1;
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int num,l,r;
char sex;
cin>>num>>sex>>l>>r;
if(l!=-1) tr[l].sex='M';
if(r!=-1) tr[r].sex='F';
tr[num]={l,r,sex};
}
int k;
cin>>k;
while(k--)
{
int a,b;
cin>>a>>b;
if(tr[a].sex==tr[b].sex) puts("Never Mind");
else
{
if(check(a,b)) puts("Yes");
else puts("No");
}
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-018 多项式A除以B
题意:
思路:模拟除法
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m;
int b[N];
double a[N],c[N],d[N];
//a[i]=m x^i的系数为m
void solve()
{
cin>>n;
int f=0;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
cin>>a[x];
if(i==0) f=x;
}
cin>>m;
for(int i=0;i<m;i++)
cin>>b[i]>>d[i];
for(int i=f;i>=b[0];i--)
{
int t=i-b[0];
c[t]=a[i]/d[0];
for(int j=0;j<m;j++)
a[t+b[j]]=a[t+b[j]]-c[t]*d[j];
}
int cntc=0,cntr=0;
for(int i=f;i>=0;i--)
{
if(fabs(c[i])>=0.05) cntc++;
if(fabs(a[i])>=0.05) cntr++;
}
cout<<cntc;
for(int i=f;i>=0;i--)
if(fabs(c[i])>=0.05)
printf(" %d %.1f",i,c[i]);
if(cntc==0) printf(" 0 0.0");
printf("\n");
cout<<cntr;
for(int i=f;i>=0;i--)
if(fabs(a[i])>=0.05)
printf(" %d %.1f",i,a[i]);
if(cntr==0) printf(" 0 0.0");
printf("\n");
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-020 功夫传人
题意:
思路:bfs/dfs
注意要先存图再搜索。
注意祖师爷为得道者的情况。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
double n;
double z,r;
int h[N],e[N],ne[N],idx;
double p[N];
double st[N];
bool vis[N];
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
double ans;
void bfs()
{
queue<int>q;
q.push(0);
vis[0]=1;
if(st[0]) ans+=p[0]*st[0];
while(q.size())
{
int t=q.front();
q.pop();
for(int i=h[t];~i;i=ne[i])
{
int j=e[i];
if(vis[j]) continue;
if(st[j])
{
p[j]=p[t]*r;
p[j]=p[j]*st[j];
ans+=p[j];
}
else
{
p[j]=p[t]*r;
}
q.push(j);
vis[j]=1;
}
}
}
void solve()
{
memset(h,-1,sizeof h);
cin>>n>>z>>r;
r = (100-r)/100;
p[0]=z;
for(int i=0;i<n;i++)
{
int k;
cin>>k;
if(k==0)
{
int x;
cin>>x;
st[i]=x;
}
else
{
for(int j=0;j<k;j++)
{
int x;
cin>>x;
add(i,x);
}
}
}
bfs();
cout<<int(ans)<<'\n';
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-021 点赞狂魔
题意:
思路:结构体排序。当人数不足3时,可以多加几个“-”
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
struct node{
string name;
int cnt;
int sum;
}a[N];
bool cmp(node a,node b)
{
if(a.cnt==b.cnt) return a.sum<b.sum;
else return a.cnt>b.cnt;
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].name>>a[i].sum;
set<int>s;
for(int j=0;j<a[i].sum;j++)
{
int x;
cin>>x;
s.insert(x);
}
a[i].cnt=s.size();
// gao(a[i].cnt);
}
a[n+1]={"-"};a[n+2]={"-"};a[n+3]={"-"};
n+=3;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=3;i++)
cout<<a[i].name<<" \n"[i==3];
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-022 重排链表
题意:
思路:创建双向链表,双指针分别位于头尾交替输出
注意:输入的结点可能是不在链表里的“废结点”,需要统计有效节点的个数cnt
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
struct node{
int data,nex;
int pre;
}l[N];
void solve()
{
int h,t;
cin>>h>>n;
for(int i=1;i<=n;i++)
{
int a,b,c;
cin>>a>>b>>c;
l[a]={b,c};
if(c==-1) t=a;
}
int H=h;
int cnt=0;//有效节点个数
while(H!=-1)
{
cnt++;
int tem=l[H].nex;
l[tem].pre=H;
H=tem;
}
for(int i=1;i<=cnt;i++)
{
if(i&1)
{
if(i!=cnt) printf("%05d %d %05d\n",t,l[t].data,h);
else printf("%05d %d -1\n",t,l[t].data);
t=l[t].pre;
}
else
{
if(i!=cnt) printf("%05d %d %05d\n",h,l[h].data,t);
else printf("%05d %d -1\n",h,l[h].data);
h=l[h].nex;
}
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-023 图着色问题
题意:
思路:set判断颜色个数是否等于k,再暴力检查是否有相邻点颜色相同。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=610;
const int inf=0x3f3f3f3f;
using namespace std;
int v,e,k;
int g[N][N];
int col[N];
int n;
bool check()
{
for(int i=1;i<=v;i++)
for(int j=1;j<=v;j++)
if(g[i][j]&&col[i]==col[j])
return 0;
return 1;
}
void solve()
{
cin>>v>>e>>k;
for(int i=1;i<=e;i++)
{
int a,b;
cin>>a>>b;
g[a][b]=1;g[b][a]=1;
}
cin>>n;
while(n--)
{
set<int>s;
for(int i=1;i<=v;i++)
{
cin>>col[i];
s.insert(col[i]);
}
if(s.size()==k)
{
if(check()) puts("Yes");
else puts("No");
}
else puts("No");
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-024 部落
题意:
思路:用并查集判断两人是否在同一个部落。用set判断这个社区的总人数、以及互不相交的部落的个数
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e4+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
int fa[N];
int find(int x)
{
return fa[x]==x? x:fa[x]=find(fa[x]);
}
void merge(int a,int b)
{
fa[find(a)]=find(b);
}
void solve()
{
cin>>n;
for(int i=0;i<N;i++) fa[i]=i;
set<int>s;
for(int i=1;i<=n;i++)
{
int k;
cin>>k;
int a;
if(k!=0) {cin>>a;s.insert(a);}
for(int j=2;j<=k;j++)
{
int x;
cin>>x;
s.insert(x);
merge(x,a);
}
}
cout<<s.size()<<' ';
set<int>cnt;
for(auto i:s)
{
cnt.insert(find(i));
}
cout<<cnt.size()<<'\n';
int q;
cin>>q;
while(q--)
{
int a,b;
cin>>a>>b;
if(find(a)==find(b)) puts("Y");
else puts("N");
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-025 分而治之
题意:
思路:方案是否可行,即是否城市之间还有通路。可以把m条边存起来,标记攻下的城市,再遍历m条边,看是否还有通路。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m;
struct node{
int x,y;
}e[N];
void solve()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
e[i]={a,b};
}
int k;
cin>>k;
while(k--)
{
map<int,bool>mp;
int cnt;
cin>>cnt;
for(int i=1;i<=cnt;i++)
{
int x;
cin>>x;
mp[x]=1;
}
bool f=0;
for(int i=1;i<=m;i++)
{
if(mp[e[i].x]==0&&mp[e[i].y]==0)
{
f=1;
puts("NO");
break;
}
}
if(!f) puts("YES");
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-026 小字辈
思路:建树,辈分最小的即为树中深度最大的。用dfs求点的深度
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
int h[N],e[N],ne[N],idx;
int dep[N],maxd;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int d)
{
dep[u]=d;
maxd=max(maxd,d);
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
dfs(j,d+1);
}
}
void solve()
{
memset(h,-1,sizeof h);
cin>>n;
int root=-1;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
if(x==-1) root=i;
else add(x,i);
}
dfs(root,1);
cout<<maxd<<'\n';
vector<int>ans;
for(int i=1;i<=n;i++)
if(dep[i]==maxd)
ans.push_back(i);
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++)
cout<<ans[i]<<" \n"[i==ans.size()-1];
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-027 名人堂与代金券
题意:
思路:结构体排序,注意排名的计算和成绩并列时的输出
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n,g,k;
struct node{
string name;
int s;
}a[N];
bool cmp(node a,node b)
{
if(a.s==b.s) return a.name<b.name;
return a.s>b.s;
}
void solve()
{
cin>>n>>g>>k;
int sum=0;
for(int i=1;i<=n;i++)
{
cin>>a[i].name>>a[i].s;
if(a[i].s>=60&&a[i].s<g) sum+=20;
else if(a[i].s>=g) sum+=50;
}
cout<<sum<<'\n';
sort(a+1,a+n+1,cmp);
int cnt=0,last=-1;
int i;
for(i=1;i<=k;i++)
{
if(a[i].s==last)
cout<<cnt<<' '<<a[i].name<<' '<<a[i].s<<'\n';
else
{
cout<<i<<' '<<a[i].name<<' '<<a[i].s<<'\n';
cnt=i;
}
// cnt=i;
last=a[i].s;
}
while(a[i].s==last)
{
cout<<cnt<<' '<<a[i].name<<' '<<a[i].s<<'\n';
i++;
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-028 秀恩爱分得快
题意:
思路:r数组存照片中的人,只计算与a和b有关的亲密度,st数组存性别。注意-0的输入和输出,输入用字符串。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1010;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m;
int st[N];
vector<int>r[N];
double pa[N],pb[N];
int change(string x)
{
bool f=0;
if(x[0]=='-') f=1;
int ret=0;
for(int i=0;i<x.length();i++)
{
if(x[i]>='0'&&x[i]<='9')
ret=ret*10+int(x[i]-'0');
}
if(f) st[ret]=-1;
return ret;
}
void solve()
{
cin>>n>>m;
for(int i=0;i<n;i++) st[i]=1;
for(int i=0;i<m;i++)
{
int k;
cin>>k;
for(int j=0;j<k;j++)
{
string s;
cin>>s;
int x=change(s);
r[i].push_back(x);
}
}
string A,B;
cin>>A>>B;
int a,b;
a=change(A);b=change(B);
bool exist_a,exist_b;
double maxa=0,maxb=0;//a,b与异性的最大亲密度
for(int i=0;i<m;i++)
{
exist_a=(find(r[i].begin(),r[i].end(),a)!=r[i].end());
exist_b=(find(r[i].begin(),r[i].end(),b)!=r[i].end());
if(exist_a||exist_b)
{
int k=r[i].size();
for(int j=0;j<k;j++)
{
if(exist_a&&st[r[i][j]]!=st[a])
{
pa[r[i][j]]+=1.0/(1.0*k);
maxa=max(maxa,pa[r[i][j]]);
}
if(exist_b&&st[r[i][j]]!=st[b])
{
pb[r[i][j]]+=1.0/(1.0*k);
maxb=max(maxb,pb[r[i][j]]);
}
}
}
}
if(maxa==pa[b]&&maxb==pb[a])
{
printf("%s%d %s%d\n",st[a]==1? "":"-",a,st[b]==1? "":"-",b);
}
else
{
for(int i=0;i<n;i++)
if(pa[i]==maxa)
printf("%s%d %s%d\n",st[a]==1? "":"-",a,st[i]==1? "":"-",i);
for(int i=0;i<n;i++)
if(pb[i]==maxb)
printf("%s%d %s%d\n",st[b]==1? "":"-",b,st[i]==1? "":"-",i);
}
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}
L2-029 特立独行的幸福
题意:
思路:我们可以把数指向他迭代的下一个数来建树。然后判断区间内每个数的祖宗节点是不是1,有没有依附来判断。
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e4+10;
const int inf=0x3f3f3f3f;
using namespace std;
int a,b;
bool st[N];
int primes[N],cnt;
void get(int n)
{
for(int i=2;i<=n;i++)
{
if(!st[i]) primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++)
{
st[i*primes[j]]=1;
if(i%primes[j]==0) break;
}
}
}
int fa[N];
int change(int x)//平方和
{
int ret=0;
while(x)
{
int t=x%10;
x/=10;
ret+=t*t;
}
return ret;
}
int num;
int find(int x)//找祖宗节点
{
num=0;
while(fa[x]!=x)
{
num++;
x=fa[x];
if(num>N) return -1;
}
return x;
}
bool check(int x)//[a,b]有没有数依附于x
{
for(int i=a;i<=b;i++)
if(fa[i]==x) return 0;
return 1;
}
void solve()
{
cin>>a>>b;
get(b);
for(int i=1;i<N;i++) fa[i]=i;
for(int i=1;i<N;i++)
fa[i]=change(i);//每个数指向其平方和
int ans=0;
for(int i=a;i<=b;i++)
{
if(find(i)==1&&check(i))
{
if(!st[i]) num*=2;
cout<<i<<' '<<num<<'\n';
ans++;
}
}
if(ans==0) puts("SAD");
}
signed main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios;
int _t=1;
//cin>>_t;
while(_t--) solve();
system("pause");
return 0;
}