天梯赛L2
- L2-001 紧急救援
- L2-002 链表去重
- L2-003 月饼
- L2-004 这是二叉搜索树吗?
- L2-005 集合相似度
- L2-006 树的遍历
- L2-011 玩转二叉树
- L2-007 家庭房产
- L2-008 最长对称子串
- L2-009 抢红包
- L2-010 排座位
- L2-012 关于堆的判断
- L2-013 红色警报
- L2-014 列车调度
- L2-015 互评成绩
- L2-016 愿天下有情人都是失散多年的兄妹
- L2-017 人以群分
- L2-018 多项式A除以B
- L2-019 悄悄关注
- L2-020 功夫传人
- L2-021 点赞狂魔021
- L2-022 重排链表
- L2-023 图着色问题
- L2-024 部落
- L2-025 分而治之
- L2-026 小字辈
- L2-027 名人堂与代金券
- L2-028 秀恩爱分得快
- L2-029 特立独行的幸福
- L2-030 冰岛人
- L2-031 深入虎穴
- L2-032 彩虹瓶
- L2-033 简单计算器
- L2-034 口罩发放
- L2-035 完全二叉树的层序遍历
- L2-036 网红点打卡攻略
- L2-037 包装机
- L2-038 病毒溯源
- L2-039 清点代码库
- L2-040 哲哲打游戏
- L2-041 插松枝
- L2-042 老板的作息表
- L2-043 龙龙送外卖
- L2-044 大众情人
- L2-045 堆宝塔
- L2-046 天梯赛的赛场安排
- L2-047 锦标赛
- L2-048 寻宝图
- L2-049 鱼与熊掌
- L2-050 懂蛇语
- L2-051 满树的遍历
- L2-052 吉利矩阵
- 203三足鼎立
L2-001 紧急救援
最短路径模板题
1.最短路径求法dist,st,g
2.不同的需求可以开不同的数组来表示,救援sum,cnt
3.求最短路径的个数num和最短路径的过程pre
#include<bits/stdc++.h>
using namespace std;
const int N=1000;
int g[N][N];
int dist[N];
bool st[N];
int pre[N],sum[N],cn[N],num[N];//路径,总共救援队,每个城市救援队,最短路劲条数
int n,m,s,d;
void dj(){
memset(dist,0x3f,sizeof dist);
dist[s]=0;
sum[s]=cn[s];
num[s]=1;
for(int i=0;i<n;i++){
int t=-1;
for(int j=0;j<n;j++)
if(!st[j]&&(t==-1||dist[j]<dist[t])){//此处有点不记得了,找没有被标记且离源点最近的点,不用加g[t][j]
t=j;
}
st[t]=true;
for(int j=0;j<n;j++){
if(dist[j]>dist[t]+g[t][j]){
dist[j]=dist[t]+g[t][j];
sum[j]=sum[t]+cn[j];
pre[j]=t;
num[j]=num[t];
}
else if(dist[j]==dist[t]+g[t][j]){
num[j]+=num[t];
if(sum[j]<sum[t]+cn[j]){
sum[j]=sum[t]+cn[j];
pre[j]=t;
}
}
}
}
}
int main(){
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++)
cin>>cn[i];
memset(g,0x3f,sizeof g);
while(m--){
int a,b,c;
cin>>a>>b>>c;
g[a][b]=g[b][a]=c;
}
dj();
cout<<num[d]<<" "<<sum[d]<<endl;
vector<int> ve;
int fa=d;
while(fa!=s){
ve.push_back(fa);
fa=pre[fa];
}
ve.push_back(s);
for(int i=ve.size()-1;i>=0;i--){
if(i==0) cout<<ve[i];
else cout<<ve[i]<<" ";
}
return 0;
}
L2-002 链表去重
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
struct node{
int data,next;
}a[N];
int main(){
int first,n;
cin>>first>>n;
set<int> s;
int del[N],pre[N];
int k1=0,k2=0;
for(int i=0;i<n;i++){
int ad;
cin>>ad;
cin>>a[ad].data>>a[ad].next;
}
int i=first;
while(a[i].next!=-1){
int num=abs(a[i].data);
if(s.count(num)){
del[k1++]=i;
}else{
pre[k2++]=i;
s.insert(num);
}
i=a[i].next;
}
//最后一个指向-1的节点不要忘记了
int num=abs(a[i].data);
if(s.count(num)){
del[k1++]=i;
}else pre[k2++]=i;
// cout<<k2<<endl;
printf("%05d %d ",pre[0],a[pre[0]].data);
for(int j=1;j<k2;j++){
printf("%05d\n",pre[j]);
printf("%05d %d ",pre[j],a[pre[j]].data);
}
cout<<"-1"<<endl;
// cout<<k1<<endl;
if(k1){
printf("%05d %d ",del[0],a[del[0]].data);
for(int j=1;j<k1;j++){
printf("%05d\n",del[j]);
printf("%05d %d ",del[j],a[del[j]].data);
}
cout<<"-1"<<endl;
}
return 0;
}
L2-003 月饼
结构体排序
#include<bits/stdc++.h>
using namespace std;
struct node{
double n,p;//库存,售价
}a[1010];
bool cmp(node a,node b){
return a.p*b.n>a.n*b.p;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>a[i].n;
for(int i=0;i<n;i++)
cin>>a[i].p;
sort(a,a+n,cmp);
double ans=0;
for(int i=0;i<n&&m;i++){
if(a[i].n<m){
m-=a[i].n;
ans+=a[i].p;
}else{
ans+=(a[i].p/a[i].n*m);
m=0;
}
}
printf("%.2lf",ans);
return 0;
}
L2-004 这是二叉搜索树吗?
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n;
int pr[N];//前序遍历
vector<int> pa;//后序遍历
bool flag;
void find(int l,int r){
if(l>r) return;
int tl=l+1,tr=r;
if(!flag){
while(tl<=r&&pr[tl]<pr[l]) tl++;
while(tr>l&&pr[tr]>=pr[l]) tr--;
}
else{
while(tl<=r&&pr[tl]>=pr[l]) tl++;
while(tr>l&&pr[tr]<pr[l]) tr--;
}
if(tl-tr!=1) return;
find(l+1,tr);
find(tl,r);
pa.push_back(pr[l]);
}
int main(){
cin>>n;
for(int i=0;i<n;i++) cin>>pr[i];
find(0,n-1);
if(pa.size()!=n){
pa.clear();
flag=true;
find(0,n-1);
}
if(pa.size()!=n) cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
for(int i=0;i<pa.size();i++)
if(i) cout<<" "<<pa[i];
else cout<<pa[i];
}
return 0;
}
L2-005 集合相似度
#include<bits/stdc++.h>
using namespace std;
const int N=10005;
int n,m,k,x;
vector<set<int>> a(N);//不能用中括号
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>m;
set<int> t;
for(int i=0;i<m;i++){
cin>>x;
t.insert(x);
}
a[i]=t;
}
cin>>k;
for(int i=0;i<k;i++){
int b,c,cnt=0;
cin>>b>>c;
for(auto itm:a[b]){
if(a[c].find(itm)!=a[c].end())//需要写!=
cnt++;
}
double ans=1.0*cnt/(a[b].size()+a[c].size()-cnt)*100;
printf("%.2lf%%\n",ans);
}
return 0;
}
L2-006 树的遍历
根据中序遍历和后序遍历建树,然后用bfs求层次遍历
#include<bits/stdc++.h>
using namespace std;
const int N=50;
struct node{
int r,l;
}a[N];
int in[N],post[N];
int build(int l1,int l2,int r1,int r2){//中序,后序
if(l1>l2) return 0;
int root=post[r2];
int p=l1;
while(in[p]!=root) p++;
int cnt=p-l1;
a[root].l=build(l1,p-1,r1,r1+cnt-1);
a[root].r=build(p+1,l2,r1+cnt,r2-1);
return root;
}
void bfs(int x){
queue<int> q;
vector<int> v;
q.push(x);
while(!q.empty()){
int t=q.front();
q.pop();
if(t==0) break;
v.push_back(t);
if(a[t].l!=0) q.push(a[t].l);
if(a[t].r!=0) q.push(a[t].r);
}
int len=v.size();
for(int i=0;i<len;i++)
printf("%d%c",v[i],i==len-1?'\n':' ');
return;
}
// void bfs(int root){//求前序遍历
// cout<<root<<" ";
// if(a[root].l!=0) bfs(a[root].l);
// if(a[root].r!=0) bfs(a[root].r);
// }
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>post[i];
for(int i=0;i<n;i++) cin>>in[i];
build(0,n-1,0,n-1);
int root=post[n-1];
bfs(root);
}
L2-011 玩转二叉树
#include<bits/stdc++.h>
using namespace std;
const int N=5000;
struct note{
int l,r;
}a[N];
int in[N],pre[N];
int build(int l1,int l2,int r1,int r2){//中,前
if(l1>l2) return 0;
int p=l1;
int root=pre[r1];
while(in[p]!=root) p++;
int cnt=p-l1;
a[root].r=build(l1,p-1,r1+1,r1+cnt);
a[root].l=build(p+1,l2,r1+cnt+1,r2);
return root;
}
void bfs(int root){
vector<int> v;
queue<int> q;
q.push(root);
while(q.size()){
int t=q.front();
q.pop();
if(t==0) break;
v.push_back(t);
if(a[t].l!=0){
q.push(a[t].l);
}
if(a[t].r!=0){
q.push(a[t].r);
}
}
for(int i=0;i<v.size();i++){
if(i) cout<<" "<<v[i];
else cout<<v[i];
}
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>in[i];
for(int i=0;i<n;i++) cin>>pre[i];
build(0,n-1,0,n-1);
int root=pre[0];
bfs(root);
return 0;
}
L2-007 家庭房产
并查集,多个数组,sz,house,area,p,st
#include<bits/stdc++.h>
using namespace std;
const int N=10100;
struct node{
int num,id;
int area,tao;
bool operator<(const node &b) const
{
if (area * b.num != b.area * num)
return area * b.num > b.area * num;
return id < b.id;
}
}a[N];
int p[N],sz[N],house[N],area[N];
int st[N];
void init(){
for(int i=0;i<N;i++){
p[i]=i,
sz[i]=1;
}
}
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void merge(int a,int b){
st[a]=st[b]=1;//这个不要忘了标记
int pa=find(a),pb=find(b);
if(pa==pb) return;
if(pa>pb) swap(pa,pb);
p[pb]=pa;
sz[pa]+=sz[pb];
house[pa]+=house[pb];
area[pa]+=area[pb];
}
int main(){
int n;
cin>>n;
int child[10];
init();
for(int i=0;i<n;i++){
int id,fa,ma,k,hou,ar;
cin>>id>>fa>>ma>>k;
st[id]=1;
for(int j=0;j<k;j++){
cin>>child[j];
}
cin>>hou>>ar;
house[find(id)]+=hou,area[find(id)]+=ar;
if(fa!=-1){
merge(id,fa);
}
if(ma!=-1)
merge(id,ma);
for(int j=0;j<k;j++){
merge(id,child[j]);
}
}
int cnt=0;
for(int i=0;i<N;i++){
if(find(i)==i&&st[i]){
a[cnt].id=i;
a[cnt].num=sz[i];
a[cnt].area=area[i];
a[cnt].tao=house[i];
cnt++;
}
}
sort(a,a+cnt);
cout<<cnt<<endl;
for(int i=0;i<cnt;i++){
printf("%04d %d %.3f %.3f\n",a[i].id,a[i].num,
a[i].tao/(float)a[i].num,a[i].area/(float)a[i].num);
}
return 0;
}
L2-008 最长对称子串
暴力,枚举长度,起点zhongdian
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int main(){
string s;
getline(cin,s);
int mx=0;
for(int len=1;len<=s.size();len++){
for(int i=0;i+len-1<s.size();i++){
int j=i+len-1;
bool flag=false;
for(int l=i,r=j;r-l>=0;l++,r--){
if(s[l]!=s[r]){
flag=true;
break;
}
}
if(!flag) mx=max(mx,len);
}
}
cout<<mx<<endl;
}
dp
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
char a[N];
int dp[N][N];//dp[i][j]表示字符串i到j是对称字符
int main() {
scanf("%[^\n]",a);
int n=strlen(a);
int ans=1;
for (int i = 0; i < n; i++){
dp[i][i] = 1;
if(a[i+1]==a[i]&&i+1<n){
dp[i][i+1]=1;
ans=2;
}
}
for (int len = 2; len <= n; len++) {
for (int i = 0; i < n - len + 1; i++) {
int j = i + len - 1;
if (a[i] == a[j]&&dp[i+1][j-1]){
dp[i][j]=1;
ans=max(ans,len);
}
}
}
cout<<ans<<endl;
return 0;
}
马拉车模型O(n)的复杂度
get_d
scanf("%[^\n],a+1);
马拉车算法——在O(n)的时间内求出一个字符串中的最长回文串
#include<bits/stdc++.h>
using namespace std;
const int N=1e7;
char a[N],s[N];
int d[N];
void get_d(char s[],int n){
d[1]=1;
for(int i=2,l,r=1;i<=n;i++){
if(i<=r) d[i]=min(d[r-i+l],r-i+1);
while(s[i-d[i]]==s[i+d[i]]) d[i]++;
if(i+d[i]-1>r) l=i-d[i]+1,r=i+d[i]-1;
}
}
int main(){
scanf("%[^\n]",a+1);
int n=strlen(a+1),k=0;
s[0]='$',s[++k]='#';
for(int i=1;i<=n;i++)
s[++k]=a[i],s[++k]='#';
n=k;
get_d(s,n);
int mx=0;
for(int i=1;i<=n;i++){
// cout<<d[i]<<endl;
mx=max(mx,d[i]-1);
}
cout<<mx<<endl;
return 0;
}
L2-009 抢红包
结构体排序
#include<bits/stdc++.h>
using namespace std;
const int N=10100;
struct note{
int num,cnt;
double mon;
bool operator<(const note& w) const{
// if(mon!=w.mon) return mon>w.mon;
// else{
// if(cnt!=w.cnt) return cnt>w.cnt;
// else return num<w.num;
// }
if(mon!=w.mon) return mon>w.mon;
else if(cnt!=w.cnt) return cnt>w.cnt;
else return num<w.num;
}
}a[N];
int main(){
int n,k;
cin>>n;
for(int i=1;i<=n;i++){
cin>>k;
a[i].num=i;
for(int j=0;j<k;j++){
int t1,t2;
cin>>t1>>t2;
a[t1].mon+=t2;
a[t1].cnt++;
a[i].mon-=t2;
}
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
printf("%d %.2lf\n",a[i].num,a[i].mon/100);
}
return 0;
}
L2-010 排座位
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int p[N];
int g[N][N];
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void unique(int a,int b){
int pa=find(a),pb=find(b);
if(pa!=pb){
p[pa]=pb;
}
}
int main(){
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<N;i++) p[i]=i;
while(m--){
int a,b,c;
cin>>a>>b>>c;
if(c==-1){
g[a][b]=g[b][a]=1;
}else{
unique(a,b);
}
}
while(k--){
int a,b;
cin>>a>>b;
int pa=find(a),pb=find(b);
if(g[a][b]){
if(pa==pb){
cout<<"OK but..."<<endl;
}else cout<<"No way"<<endl;
}else{
if(pa==pb) cout<<"No problem"<<endl;
else cout<<"OK"<<endl;
}
}
return 0;
}
L2-012 关于堆的判断
make_heap建堆
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
// priority_queue<int,vector<int>,greater<int> > h;
map<int,int> mp;
int n,m;
vector<int> hp(0,0);
int main(){
cin>>n>>m;
int x;
for(int i=1;i<=n;i++){
cin>>x;
hp.push_back(x);
make_heap(hp.begin(),hp.end(),greater<int>());
}
for(int i=0;i<n;i++){
// mp.insert({hp[i],i+1});
mp[hp[i]]=i+1;
}
while(m--){
int a,b;
string s;
cin>>a>>s;
if(s[0]=='a'){
cin>>b>>s>>s;
cout<<(mp[a]/2==mp[b]/2?"T":"F")<<endl;
// cout<<(abs(mp[a]-mp[b])==1?"T":"F")<<endl;//不能用这个判断,因为两个相邻的数都可以,例如5,6
}else{
cin>>s>>s;
if(s[0]=='r'){
if(mp[a]==1) cout<<"T"<<endl;
else cout<<"F"<<endl;
}else if(s[0]=='p'){
cin>>s>>b;
cout<<(mp[a]==mp[b]/2?"T":"F")<<endl;
}else{
cin>>s>>b;
cout<<(mp[a]/2==mp[b]?"T":"F")<<endl;
}
}
}
return 0;
}
L2-013 红色警报
多次遍历求连通块的个数
#include<bits/stdc++.h>
using namespace std;
const int N=5050;
int n,m,k,last_cnt,cnt,u;
int g[N][N];
bool st[N];
void dfs(int u){
st[u]=true;
for(int i=0;i<n;i++){
if(g[u][i]&&!st[i])
dfs(i);
}
}
int main(){
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
g[a][b]=g[b][a]=1;
}
for(int i=0;i<n;i++){
if(!st[i]){
dfs(i);
++last_cnt;
}
}
cin>>k;
int flag=n;
while(k--){
cin>>u;
flag--;
for(int i=0;i<n;i++){
g[u][i]=g[i][u]=0;
}
memset(st,0,sizeof st);
cnt=0;
for(int i=0;i<n;i++){
if(!st[i])
dfs(i),++cnt;
}
if(last_cnt+1<cnt)
printf("Red Alert: City %d is lost!\n",u);
else
printf("City %d is lost.\n",u);
last_cnt=cnt;
}
if(!flag) printf("Game Over.\n");
return 0;
}
L2-014 列车调度
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
set<int> s;
cin>>n;
s.insert(1e5+5);
while(n--){
int x;
cin>>x;
if(x<*s.rbegin()){
s.erase(*s.upper_bound(x));
}
s.insert(x);
}
cout<<s.size();
return 0;
}
L2-015 互评成绩
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int main(){
int n,m,k,x;
vector<int> v;
cin>>n>>m>>k;
for(int i=0;i<n;i++){
int mx=-5,mn=105,cnt=0;
for(int j=0;j<m;j++){
cin>>x;
mx=max(mx,x),mn=min(mn,x);
cnt+=x;
}
// cout<<cnt<<endl;
v.push_back(cnt-mx-mn);
}
// cout<<endl;
sort(v.begin(),v.end(),greater<int>());
// for(auto itm:v) cout<<itm<<endl;
// cout<<endl<<m<<endl;
for(int i=k-1;i>=0;i--){
if(i) printf("%.3lf ",1.0*v[i]/(m-2));
else printf("%.3lf",1.0*v[i]/(m-2));//除要记得括号
}
return 0;
}
L2-016 愿天下有情人都是失散多年的兄妹
bfs将两个待查询的人的五代放进set进行判重
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N=1e6+10;//段错误说明指针越界了,数组开小了1e4+10不行
char sex[N];
vector<int> v[N];//v(N)表示一维数组,v[N]表示二维数组
bool bfs(int a,set<int> &s){
queue<pii> q;
q.push({a,1});
while(q.size()){
auto t=q.front();
q.pop();
int x=t.first,h=t.second;
if(s.count(x)) return false;
s.insert(x);
for(int i=0;i<v[x].size();i++)
if(h<5)
q.push({v[x][i],h+1});
}
return true;
}
int main(){
int n,k;
cin>>n;
int id,fa,ma;
char se[2];
while(n--){
cin>>id>>se>>fa>>ma;
sex[id]=se[0];
if(fa!=-1){
v[id].push_back(fa);
sex[fa]='M';//双亲性别记得标记,不然有测试点过不去
}
if(ma!=-1){
v[id].push_back(ma);
sex[ma]='F';
}
}
cin>>k;
while(k--){
int a,b;
cin>>a>>b;
// cout<<sex[a]<<" "<<sex[b]<<endl;
if(sex[a]==sex[b]) cout<<"Never Mind"<<endl;
else{
set<int> st;
st.clear();
bfs(a,st);
if(bfs(b,st)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
return 0;
}
L2-017 人以群分
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
long long cnt1,cnt2;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
sort(a,a+n);
for(int i=0;i<n;i++){
if(i<n/2) cnt1+=a[i];
else cnt2+=a[i];
}
long long ans=cnt2-cnt1;
if(n%2){
printf("Outgoing #: %d\n",n/2+1);
printf("Introverted #: %d\n",n/2);
printf("Diff = %lld",ans);
}else{
printf("Outgoing #: %d\n",n/2);
printf("Introverted #: %d\n",n/2);
printf("Diff = %lld",ans);
}
}
L2-018 多项式A除以B
#include<bits/stdc++.h>
using namespace std;
const int N=100000;
double a[N],b[N],c[N];
int ma,mb;
int sc(double t[],int start){
int cnt=0;
for(int i=start;i>=0;i--)
if(fabs(t[i])>0.05) cnt++;
return cnt;
}
void print(double t[],int start){
printf("%d",sc(t,start));
if(sc(t,start)==0) printf(" 0 0.0");
else{
for(int i=start;i>=0;i--){
if(fabs(t[i])>0.05)
printf(" %d %.1lf",i,t[i]);
}
}
}
int main(){
int n,m;
cin>>n;
int k;
for(int i=0;i<n;i++){
cin>>k;
cin>>a[k];
ma=max(ma,k);
}
cin>>m;
for(int i=0;i<m;i++){
cin>>k;
cin>>b[k];
mb=max(mb,k);
}
int t1=ma,t2=mb;
while(ma>=mb){
double t=a[ma]/b[mb];
c[ma-mb]=t;
for(int i=ma,j=mb;j>=0;j--,i--) a[i]-=b[j]*t;
while(fabs(a[ma])<0.00001) ma--;
}
print(c,t1-t2);
printf("\n");
print(a,ma);
return 0;
}
L2-019 悄悄关注
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
int main(){
int n,m;
cin>>n;
string s;
double x,sum=0;
set<string> se;
map<string,double> mp;
while(n--){
cin>>s;
se.insert(s);
}
cin>>m;
n=m;
while(m--){
cin>>s>>x;
mp[s]=x;
sum+=x;
}
double avg=sum*1.0/n;
bool f=false;
for(auto it:mp){
if(it.y>avg&&!se.count(it.x)){
cout<<it.x<<endl;
f=true;
}
}
if(!f) cout<<"Bing Mei You";
return 0;
}
L2-020 功夫传人
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> a[N];
int d[N];//d[i]为编号为i得道者的放大倍数
int n;
double z,r,ans;
void dfs(int u,int cnt){//cnt表示当前为第cnt代
if(!a[u].size()){
ans+=d[u]*z*pow(r,cnt);
}
for(int i=0;i<a[u].size();i++){
dfs(a[u][i],cnt+1);
}
}
int main(){
cin>>n>>z>>r;
r=(100-r)/100;
for(int i=0;i<n;i++){
int k;
cin>>k;
if(!k) cin>>d[i];
for(int j=0;j<k;j++){
int x;
cin>>x;
a[i].push_back(x);
}
}
dfs(0,0);
printf("%d\n",(int)ans);//取整数技巧
return 0;
}
L2-021 点赞狂魔021
#include<bits/stdc++.h>
using namespace std;
const int N=1000;
struct note{
string name;
int cnt;
double avg;
bool operator<(const note& w) const{
if(cnt!=w.cnt) return cnt>w.cnt;
return avg>w.avg;
}
}a[N];
int main(){
int n,k;
cin>>n;
string s;
for(int i=0;i<n;i++){
cin>>s>>k;
set<int> st;
int cnt=0;
for(int j=0;j<k;j++){
int x;
cin>>x;
if(st.count(x)) continue;
st.insert(x);
cnt++;
}
a[i].name=s,a[i].cnt=cnt,a[i].avg=1.0*cnt/k;
}
sort(a,a+n);
// for(int i=0;i<n;i++){
// cout<<a[i].name<<" "<<a[i].cnt<<" "<<a[i].avg<<endl;
// }
if(n>=3){
for(int i=0;i<3;i++)
if(i) cout<<" "<<a[i].name;
else cout<<a[i].name;
}else if(n==2){
cout<<a[0].name<<" "<<a[1].name<<" "<<"-";
}else if(n==1){
cout<<a[0].name<<" "<<"-"<<" "<<"-";
}else
cout<<"-"<<" "<<"-"<<" "<<"-";
return 0;
}
L2-022 重排链表
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct note{
string add,next;
int data;
}a[N],q;
string head;
map<string,pair<int,string>> mp;
int n;
int main(){
cin>>head>>n;
for(int i=0;i<n;i++){
string add,next;
int data;
cin>>add>>data>>next;
mp[add]={data,next};
}
//将答案下标转移到0~cnt-1
int cnt=0;
while(head!="-1"){
a[cnt].add=head;
a[cnt++].data=mp[head].first;
head=mp[head].second;
}
for(int l=0,r=cnt-1;l<=r;l++,r--){
if(l!=r){
cout<<a[r].add<<" "<<a[r].data<<" "<<a[l].add<<endl;
cout<<a[l].add<<" "<<a[l].data<<" "<<((l+1==r)?"-1":a[r-1].add)<<endl;
}
else
cout<<a[l].add<<" "<<a[l].data<<" "<<"-1"<<endl;
}
return 0;
}
L2-023 图着色问题
#include<bits/stdc++.h>
using namespace std;
const int N=550;
vector<int> g[N];
bool st[N];
int color[N];
int v,e,k,n;
bool dfs(int u){
st[u]=true;
// for(int i=0;i<g[u].size();i++){//上面注意对应的点是g[u][i]
// if(color[u]==color[g[u][i]]) return false;
// if(st[g[u][i]]) continue;
// if(!dfs(g[u][i])) return false;
// }
for(auto i:g[u]){
if(color[u]==color[i]) return false;
if(st[i]) continue;
if(!dfs(i)) return false;
}
return true;
}
int main(){
cin>>v>>e>>k;
while(e--){
int a,b;
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
cin>>n;
while(n--){
set<int> s;
for(int i=1;i<=v;i++){
cin>>color[i];
s.insert(color[i]);
}
if(s.size()!=k){
cout<<"No"<<endl;
continue;
}
memset(st,false,sizeof st);
bool flag=false;
for(int i=1;i<=v;i++){
if(!st[i]){
if(!dfs(i)){
cout<<"No"<<endl;
flag=true;
break;
}
}
}
if(!flag) cout<<"Yes"<<endl;
}
return 0;
}
L2-024 部落
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int p[N];
int n,k;
bool st[N];
void init(){
for(int i=0;i<N;i++) p[i]=i;
}
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void unite(int a,int b){
int pa=find(a),pb=find(b);
if(pa!=pb){
p[pa]=pb;
}
}
int main(){
init();
cin>>n;
set<int> se;
int x;
while(n--){
cin>>k;
int t;
cin>>t;
se.insert(t);
st[t]=true;
for(int i=1;i<k;i++){
cin>>x;
se.insert(x);
unite(x,t);
st[x]=true;
}
}
int cnt=0;
// for(int i=1;i<N;i++){
// if(st[i]&&p[i]==i)
// cnt++;
// }
for(auto i:se){
if(p[i]==i)
cnt++;
}
cout<<se.size()<<" "<<cnt<<endl;
int q;
cin>>q;
while(q--){
int a,b;
cin>>a>>b;
if(find(a)==find(b)) cout<<"Y"<<endl;
else cout<<"N"<<endl;
}
return 0;
}
L2-025 分而治之
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int n,m,k;
struct note{
int a,b;
}e[N];
bool st[N];
int main(){
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
e[i]={a,b};
}
cin>>k;
while(k--){
int np;
cin>>np;
int x;
memset(st,false,sizeof st);
for(int i=0;i<np;i++){
cin>>x;
st[x]=true;
}
bool flag=false;
for(int i=0;i<m;i++){
int a=e[i].a,b=e[i].b;
if(!st[a]&&!st[b]){
cout<<"NO"<<endl;
flag=true;
break;
}
}
if(!flag) cout<<"YES"<<endl;
}
return 0;
}
L2-026 小字辈
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> v[N],h[N];
int mx=0;
void bfs(int root,int hg){
queue<pair<int,int>> q;
q.push({root,hg});
while(!q.empty()){
auto t=q.front();
q.pop();
int x=t.first,hi=t.second;
h[hi].push_back(x);
mx=max(mx,hi);
for(auto it:v[x]){
q.push({it,hi+1});
}
}
}
int main(){
int n,root;
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
if(x==-1) root=i;
else{
v[x].push_back(i);
}
}
bfs(root,1);
cout<<mx<<endl;
for(int i=0;i<h[mx].size();i++){
if(i) cout<<" "<<h[mx][i];
else cout<<h[mx][i];
}
return 0;
}
L2-027 名人堂与代金券
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
struct node{
string name;
int num;
bool operator<(const node& w) const{
if(num!=w.num) return num>w.num;
else return name<w.name;
}
}a[N];
int main(){
int n,g,k;
cin>>n>>g>>k;
int sum=0;
for(int i=0;i<n;i++){
string name;
int num;
cin>>name>>num;
if(num>=g) sum+=50;
else if(num<g&&num>=60) sum+=20;
a[i]={name,num};
}
cout<<sum<<endl;
sort(a,a+n);
// for(int i=0;i<n;i++){
// cout<<a[i].name<<" "<<a[i].num<<endl;
// }
int cnt=1;
for(int i=0;i<n;i++){
cout<<cnt<<" "<<a[i].name<<" "<<a[i].num<<endl;
int j=i+1;
while(a[i].num==a[j].num){
cout<<cnt<<" "<<a[j].name<<" "<<a[j].num<<endl;
j++;
}
int len=j-i;
cnt+=len;
i=j-1;//这个不要忘了
if(cnt>k) break;
}
return 0;
}
L2-028 秀恩爱分得快
#include<bits/stdc++.h>
using namespace std;
const int N=1100;
double g[N][N];
double mx_a,mx_b;//要用double类型,用int类型寄,mx_a表示a新密度最高的异性值
int ph[N],sex[N];
vector<int> ans_a,ans_b;
int main(){
// memset(sex,-1,sizeof sex);
// fill(sex,sex+N,-1);
int n,m,k;
cin>>n>>m;
for(int i=0;i<m;i++){
cin>>k;
string s;
for(int j=0;j<k;j++){
cin>>s;
int t=fabs(stoi(s));
if(s[0]=='-') sex[t]=1;//女性
else sex[t]=0;
ph[j]=t;
}
for(int j=0;j<k;j++){
for(int z=j+1;z<k;z++){
if(sex[ph[j]]^sex[ph[z]])
g[ph[j]][ph[z]]=g[ph[z]][ph[j]]+=1.0/k;
}
}
}
string a,b;
cin>>a>>b;
int na=fabs(stoi(a)),nb=fabs(stoi(b));
for(int i=0;i<n;i++){
if(g[na][i]>mx_a&&sex[na]^sex[i]){
mx_a=g[na][i];
ans_a.clear();
ans_a.push_back(i);
}else if(g[na][i]==mx_a&&sex[na]^sex[i]){
ans_a.push_back(i);
}
if(g[nb][i]>mx_b&&sex[nb]^sex[i]){
mx_b=g[nb][i];
ans_b.clear();
ans_b.push_back(i);
}else if(g[nb][i]==mx_b&&sex[nb]^sex[i]){
ans_b.push_back(i);
}
}
if(g[na][nb]==mx_a&&g[na][nb]==mx_b){
cout<<a<<" "<<b;
}else{
// cout<<"hhh"<<endl;
for(auto x:ans_a){
cout<<a<<" ";
if(sex[x]==1) cout<<'-';
cout<<x<<endl;
}
for(auto x:ans_b){
cout<<b<<" ";
if(sex[x]==1) cout<<'-';
cout<<x<<endl;
}
}
return 0;
}
L2-029 特立独行的幸福
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int num[N],st[N];//不是独立的幸福数标记一下
bool isprime(int x){
if(x<2) return false;
for(int i=2;i<=x/i;i++){
if(x%i==0)
return false;
}
return true;
}
bool check(int x){
set<int> se;
int t=x;
while(t!=1){
se.insert(t);
int t1=t,t2=0;
while(t1){
int v=t1%10;
t2+=v*v;
t1=t1/10;
}
num[x]++;
t=t2;
st[t2]=1;
if(se.count(t2)) return false;
}
return true;
}
int main(){
int a,b;
vector<int> ans;
cin>>a>>b;
for(int i=a;i<=b;i++){
if(check(i)) ans.push_back(i);
}
// for(auto i:ans){
// cout<<i<<" "<<num[i]<<endl;
// }
bool flag=false;
for(auto i:ans){
int res=num[i];
if(isprime(i)) res=num[i]*2;
if(!st[i]){
cout<<i<<" "<<res<<endl;
flag=true;
}
}
if(!flag) cout<<"SAD"<<endl;
return 0;
}
L2-030 冰岛人
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef pair<int,string> pis;
string m,x,temp;
map<string,pis> r;
string check(string a,string b){
int cnt1=0,cnt2;
while(a!=""){
cnt2=0;
string b1=b;
while(b1!=""){
if(a==b1&&(cnt1<4||cnt2<4)) return "No\n";
if(cnt1>=4&&cnt2>=4) return "Yes\n";
b1=r[b1].second;
cnt2++;
}
cnt1++;
a=r[a].second;
}
return "Yes\n";
}
//答案错误3,6。两个人有共同祖先,是一个人的三代,另一个人的六代,也不行
// string check(string a,string b){
// set<string> s;
// int cnt=0;
// while(a!=""){
// s.insert(a);
// cnt++;
// a=r[a].second;
// if(cnt>=4) break;
// }
// cnt=0;
// while(b!=""){
// if(s.count(b)) return "No\n";
// s.insert(b);
// b=r[b].second;
// cnt++;
// if(cnt>=4) break;
// }
// return "Yes\n";
// }
int main(){
int n;
cin>>n;
while(n--){
cin>>m>>x;
if(x.back()=='n') r[m]={1,x.substr(0,x.size()-4)};//男标记1
else if(x.back()=='r') r[m]={0,x.substr(0,x.size()-7)};
else if(x.back()=='m') r[m].first=1;
else r[m].first=0;
}
int q;
cin>>q;
while(q--){
cin>>m>>temp>>x>>temp;
if(!r.count(m)||!r.count(x)) cout<<"NA\n";
else if(r[m].first==r[x].first) cout<<"Whatever\n";
else cout<<check(m,x);
}
return 0;
}
L2-031 深入虎穴
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
vector<int> v[N];
queue<int> q;
int st[N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
int k,x;cin>>k;
for(int j=0;j<k;j++){
cin>>x;
v[i].push_back(x);
v[x].push_back(i);//双向边,不要忘了
}
}
q.push(1);
st[1]=1;
int t;
while(q.size()){
t=q.front();
q.pop();
for(auto i:v[t]){
if(st[i]) continue;
st[i]=1;//注意标记,不然会内存超限
q.push(i);
}
}
cout<<t<<endl;
return 0;
}
L2-032 彩虹瓶
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,k,x;
cin>>n>>m>>k;
for(int i=0;i<k;i++){
stack<int> sk;
int cnt=1;
// bool flag=false;
// for(int j=0;j<n;j++){
// cin>>x;
// if(x==cnt){
// cnt++;
// while(sk.size()&&sk.top()==cnt){
// cnt++;
// sk.pop();
// }
// }else{
// sk.push(x);//要放前面不然会错误
// if(sk.size()>m){
// flag=true;
// }
// }
// }
// if(!sk.size()&&!flag) cout<<"YES\n";
// else cout<<"NO\n";
for(int j=0;j<n;j++){
cin>>x;
if(x==cnt){
cnt++;
while(sk.size()&&sk.top()==cnt){
cnt++;
sk.pop();
}
}else if(sk.size()<m) sk.push(x);
}
if(!sk.size()) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}
L2-033 简单计算器
#include<bits/stdc++.h>
using namespace std;
const int N=1050;
stack<int> s1;
stack<char> s2;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int x;cin>>x;
s1.push(x);
}
for(int i=0;i<n-1;i++){
char a[2];cin>>a;
s2.push(a[0]);
}
while(s2.size()&&s1.size()){
int n1=s1.top();s1.pop();
int n2=s1.top();s1.pop();
char op=s2.top();s2.pop();
if(op=='/'&&n1==0){
cout<<"ERROR: "<<n2<<'/'<<n1<<endl;
return 0;
}
int ans;
if(op=='+') ans=n1+n2,s1.push(ans);
else if(op=='-') ans=n2-n1,s1.push(ans);
else if(op=='*') ans=n1*n2,s1.push(ans);
else if(op=='/') ans=n2/n1,s1.push(ans);
}
cout<<s1.top()<<endl;
return 0;
}
L2-034 口罩发放
#include<bits/stdc++.h>
using namespace std;
const int N=3e4+10;
struct note{
string name,code;
int h;
int hh,mm;
int num;
}a[N];
bool cmp(note a,note b){
if(a.hh!=b.hh) return a.hh<b.hh;
else if(a.mm!=b.mm) return a.mm<b.mm;
else return a.num<b.num;
}
set<pair<string,string>> se;//unordered_set不能用pair元素
map<string,int> mp;
vector<pair<string,string>> ans;
bool check(string s){
if(s.size()!=18) return false;
for(int i=0;i<s.size();i++)
if(!isdigit(s[i]))
return false;
return true;
}
int main(){
int d,p,s,t;
string name,code;
int h,hh,mm;
cin>>d>>p;
for(int k=0;k<d;k++){
cin>>t>>s;
int cnt=0;
for(int i=0;i<t;i++){
cin>>name>>code>>h;
scanf("%d:%d",&hh,&mm);
if(check(code)){
a[cnt]={name,code,h,hh,mm,cnt};//又是cnt这里栽了一下
if(h==1)
ans.push_back({name,code});
// se.insert({name,code});
//对于code合格并且健康状况不好的要先存起来,
//不能用se判重,因为set会自动按字母顺序排序,而输出要求是谁先出现谁先输出
cnt++;
}
}
sort(a,a+cnt,cmp);
for(int i=0;i<cnt;i++){
if(s&&(!mp.count(a[i].code)||(k-mp[a[i].code])>=p+1)){
cout<<a[i].name<<" "<<a[i].code<<endl;
s--;
mp[a[i].code]=k;//要放里面,拿了口罩才标记
}
}
}
for(auto it:ans){
if(se.count(it)) continue;
se.insert(it);
cout<<it.first<<" "<<it.second<<endl;
}
// for(auto it:se){
// cout<<it.first<<" "<<it.second<<endl;
// }
return 0;
}
L2-035 完全二叉树的层序遍历
根据下标输入
#include<bits/stdc++.h>
using namespace std;
const int N=40;
int a[N];
int n;
void build(int x){
if(x>n) return;
build(x<<1),build((x<<1)+1);
cin>>a[x];
}
int main(){
cin>>n;
build(1);
for(int i=1;i<=n;i++)
cout<<(i==1?"":" ")<<a[i];
return 0;
}
L2-036 网红点打卡攻略
#include<bits/stdc++.h>
using namespace std;
const int N=210;
int d[N][N];
int path[N];
int main(){
int n,m,k;
cin>>n>>m;
while(m--){
int a,b,t;
cin>>a>>b>>t;
d[a][b]=d[b][a]=t;
}
cin>>k;
int cnt=0,number,ans=1e9+10;
for(int z=1;z<=k;z++){
int num;
cin>>num;
set<int> se;
fill(path,path+N,0);//记得初始化,不然不能用path[0],path[num+1]是0
for(int i=1;i<=num;i++){
cin>>path[i];
se.insert(path[i]);
}
if(num!=n||se.size()!=n) continue;
bool flag=false;
int sum=0;
for(int i=1;i<=num+1;i++){
if(d[path[i-1]][path[i]]==0){
flag=true;
break;
}
sum+=d[path[i-1]][path[i]];
}
if(flag) continue;
cnt++;
if(sum<ans){
number=z;
ans=sum;
}
}
cout<<cnt<<endl<<number<<" "<<ans<<endl;
return 0;
}
L2-037 包装机
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
queue<char> q[N];
vector<char> v;
stack<char> sk;
int main(){
int n,m,s;
cin>>n>>m>>s;
for(int i=1;i<=n;i++){
string t;
cin>>t;
for(int j=0;j<t.size();j++)
q[i].push(t[j]);
}
int t;
while(cin>>t){
if(t==-1) break;
if(t==0){
if(sk.size()){
v.push_back(sk.top());
sk.pop();
}
}else{
if(q[t].size()==0) continue;//当上面队列个数为零,不推,零操作,最后一个测试点
if(sk.size()==s){
v.push_back(sk.top());
sk.pop();
}
if(q[t].size()){
sk.push(q[t].front());
q[t].pop();
}
}
}
for(int i=0;i<v.size();i++)
cout<<v[i];
return 0;
}
L2-038 病毒溯源
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
vector<int> v[N],ans;
int in[N],pa[N];
queue<pair<int,int>> q;
int len;
int main(){
int n,k,x,res;
cin>>n;
for(int i=0;i<n;i++){
cin>>k;
for(int j=0;j<k;j++){
cin>>x;
v[i].push_back(x);
pa[x]=i;
in[x]++;
}
sort(v[i].begin(),v[i].end());
}
//找源头方法 1.遍历每个点dfs. 2.标记入度,入度为零即源头
int root;
for(int i=0;i<n;i++) if(in[i]==0) root=i;
q.push({root,1});
while(q.size()){
auto t=q.front();
q.pop();//记得弹出,不然内存超限
int s=t.first,h=t.second;
if(len<h){
len=h;//最长长度
res=s;//最后一个病毒变异株
}
for(auto it:v[s]){
q.push({it,h+1});
}
}
cout<<len<<endl;
while(res!=root){
ans.push_back(res);
res=pa[res];
}
ans.push_back(res);
for(int i=ans.size()-1;i>=0;i--)
cout<<ans[i]<<(i==0?"\n":" ");
return 0;
}
L2-039 清点代码库
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
vector<int> temp;
map<vector<int>,int> a;
multimap<int,vector<int>,greater<int> > b;
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
temp.clear();
for(int j=0;j<m;j++){
int x;
cin>>x;
temp.push_back(x);
}
a[temp]++;
}
cout<<a.size()<<endl;
for(auto it:a)
b.insert({it.second,it.first});
// b[it.second]=it.first;//不能用这个,因为multimap容器可以key重复,value不同
for(auto it:b){
cout<<it.first;
for(auto it2:it.second) cout<<" "<<it2;
cout<<endl;
}
return 0;
}
L2-040 哲哲打游戏
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
int pos;
vector<int> path;
};
int n,m,k,now=1,x;
vector<int> temp,e[N];
vector<node> save(105);
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>k;
for(int j=0;j<k;j++){
cin>>x;
e[i].push_back(x);
}
}
temp.push_back(1);//起始剧情记得加入
while(m--){
int op;
cin>>op>>x;
if(op==0){
temp.push_back(e[now][x-1]);
now=e[now][x-1];
}else if(op==1){
save[x].pos=now;
save[x].path=temp;
cout<<now<<endl;
}else{
now=save[x].pos;
temp=save[x].path;
}
}
cout<<temp.back();
return 0;
}
L2-041 插松枝
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n,m,k,x,last=INT_MAX;
queue<int> q;//deque
stack<int> sk;
vector<int> ans;
void outprint(){
for(int i=0;i<ans.size();i++)
cout<<(i==0?"":" ")<<ans[i];
cout<<endl;
ans.clear();
last=INT_MAX;//容易忘初始化
}
int main(){
cin>>n>>m>>k;
for(int i=0;i<n;i++){
cin>>x;
q.push(x);
}
while(q.size()||sk.size()){
if(sk.size()&&sk.top()<=last){
ans.push_back(sk.top());
last=sk.top();
sk.pop();
if(ans.size()==k) outprint();
}else{
if(!q.size()) outprint();
else{
int t=q.front();
if(t<=last){
ans.push_back(t);
last=t;
q.pop();
if(ans.size()==k) outprint();
}else{
if(sk.size()<m){
sk.push(t);
q.pop();
}else{
outprint();
}
}
}
}
}
if(ans.size()) outprint();
return 0;
}
L2-042 老板的作息表
#include <iostream>
#include <set>
using namespace std;
set<pair<string, string> > record;
string work_start_time, work_end_time, last_start = "00:00:00";
int main() {
cin >> work_start_time;
while (cin >> work_start_time >> work_end_time >> work_end_time) record.insert({work_start_time, work_end_time});
record.insert({"23:59:59", ""});
for (auto ite : record) {
if (last_start < ite.first) cout << last_start << " - " << ite.first << '\n';
last_start = ite.second;
}
return 0;
}
L2-043 龙龙送外卖
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int sum,mx;
int p[N],d[N];//存放父节点,d存放到根节点的距离
int dfs(int u){//返回到根节点的距离
if(p[u]==-1||d[u]>0) return d[u];
sum++;
d[u]=dfs(p[u])+1;
return d[u];
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>p[i];
while(m--){
int x;
cin>>x;
mx=max(mx,dfs(x));
cout<<sum*2-mx<<endl;
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
typedef pair<int,int> pii;
vector<int> child[N];
int parent[N],d[N],st[N],n,m,sum,mx;
queue<pii> q;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
int pn;
cin>>pn;
if(pn<0) parent[0]=i;//外买站为i
else child[pn].push_back(i);
parent[i]=pn;
}
st[parent[0]]=1;
q.push({parent[0],0});
while(!q.empty()){
int id=q.front().first,deep=q.front().second;
q.pop();
d[id]=deep;
for(auto ite:child[id]) q.push({ite,deep+1});
}
for(int i=0;i<m;i++){
int newadd;
cin>>newadd;
int passadd=newadd;
while(!st[passadd]){
st[passadd]=1;
passadd=parent[passadd];
}
sum+=d[newadd]-d[passadd];
mx=max(mx,d[newadd]);
cout<<sum*2-mx<<endl;
}
return 0;
}
L2-044 大众情人
#include<bits/stdc++.h>
using namespace std;
const int N=505,inf=0x3f3f3f3f;
int d[N][N];
char sex[N];
int main(){
int n;scanf("%d",&n);
memset(d,0x3f,sizeof d);
for(int i=0;i<=n;i++) d[i][i]=0;
for(int i=1;i<=n;i++){
char s[2];
int cnt;
scanf("%s%d",s,&cnt);
sex[i]=s[0];
while(cnt--){
int id,dist;
scanf("%d:%d",&id,&dist);
d[i][id]=dist;
}
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
for(auto c:string("FM")){
int mn=inf;
for(int i=1;i<=n;i++){
if(sex[i]==c){
int mx=0;
for(int j=1;j<=n;j++)
if(sex[j]!=sex[i])
mx=max(mx,d[j][i]);
mn=min(mn,mx);
}
}
bool f=false;
for(int i=1;i<=n;i++){
if(sex[i]==c){
int mx=0;
for(int j=1;j<=n;j++)
if(sex[j]!=sex[i])
mx=max(mx,d[j][i]);
if(mx==mn){
if(!f){
printf("%d",i);
f=true;
}else
printf(" %d",i);
}
}
}
puts("");
}
return 0;
}
L2-045 堆宝塔
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
stack<int> a,b;
int ans=0,len=0;
void outp(stack<int> &s){
int cnt=0;
while(s.size()){
s.pop();
cnt++;
}
len=max(cnt,len);
}
int main(){
int n,x;
cin>>n;
for(int i=0;i<n;i++){
cin>>x;
if(a.size()==0||x<a.top()){
a.push(x);
}else{
if(b.size()==0||b.top()<x){
b.push(x);
}else{
ans++;
outp(a);
while(b.size()&&b.top()>x){
a.push(b.top());
b.pop();
}
a.push(x);
}
}
}
if(a.size()) outp(a),ans++;
if(b.size()) outp(b),ans++;
cout<<ans<<" "<<len;
return 0;
}
L2-046 天梯赛的赛场安排
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
int a[N],cnt;
priority_queue<int> q;//heap
int main(){
int n,c;
cin>>n>>c;
for(int i=0;i<n;i++){
string name;
int num;
cin>>name>>num;
cout<<name<<" "<<ceil(1.0*num/c)<<endl;
cnt+=num/c;
if(num%c) q.push(num%c);
}
int count=0;
while(!q.empty()){
auto t=q.top();
q.pop();
bool flag=false;
for(int i=0;i<count;i++){
if(a[i]+t<=c){
a[i]+=t;
flag=true;
break;//不要忘了这个,不然后面满足条件的a[i]都会被改变
}
}
if(!flag){
a[count++]=t;
}
}
cout<<cnt+count;
return 0;
}
L2-047 锦标赛
#include<bits/stdc++.h>
using namespace std;
int ans[1<<18],lost[19][1<<18],win[19][1<<18];
int main(){
int k,w;
cin>>k;
for(int i=1;i<=k;i++){
for(int j=0;j<(1<<(k-i));j++){
cin>>lost[i][j];
if(i==1){
ans[j<<1]=lost[i][j];
win[i][j]=j<<1|1;
}else{
if(lost[i][j]<lost[i-1][j<<1]&&lost[i][j]<lost[i-1][j<<1|1]){
cout<<"No Solution\n";
return 0;
}else if(lost[i][j]>=lost[i-1][j<<1]){
ans[win[i-1][j<<1]]=lost[i][j];
win[i][j]=win[i-1][j<<1|1];
}else{
ans[win[i-1][j<<1|1]]=lost[i][j];
win[i][j]=win[i-1][j<<1];
}
lost[i][j]=max(lost[i][j],max(lost[i-1][j<<1],lost[i-1][j<<1|1]));
}
}
}
cin>>w;
if(lost[k][0]>w){
cout<<"No Solution\n";
return 0;
}
ans[win[k][0]]=w;
for(int i=0;i<(1<<k);i++){
if(i==0) cout<<ans[i];
else cout<<" "<<ans[i];
}
return 0;
}
L2-048 寻宝图
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m;
int dx[]={0,-1,0,1},dy[]={-1,0,1,0};
int ans,cnt;
// char g[N][N];内存会超限
string g[N];
bool flag;
void dfs(int x,int y){
if(g[x][y]!='1') flag=true;
g[x][y]='0';
for(int i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(tx>=0&&tx<n&&ty>=0&&ty<m&&g[tx][ty]!='0')
dfs(tx,ty);
}
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>g[i];
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]!='0'){
flag=false;
ans++;
dfs(i,j);
if(flag) cnt++;
}
}
}
cout<<ans<<" "<<cnt;
return 0;
}
L2-049 鱼与熊掌
法一:折半查找binary_search的用法,返回0或者1
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
vector<int> ve[N];
int main(){
int n,m,k,x;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>k;
while(k--){
cin>>x;
ve[x].push_back(i);
}
}
int q;cin>>q;
while(q--){
int ans=0;
int a,b;cin>>a>>b;
for(int i=1;i<=n;i++){
if(binary_search(ve[a].begin(),ve[a].end(),i)&&binary_search(ve[b].begin(),ve[b].end(),i)){
ans++;
}
}
cout<<ans<<endl;
}
}
法二:set查找法
//这个会卡输入时间,要关流
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
set<int> st[N];
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);//需要关流,不然最后一个点会超时
int n,m,k,q,x;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>k;
while(k--){
cin>>x;
st[x].insert(i);
}
}
cin>>q;
while(q--){
int a,b,ans=0;cin>>a>>b;
for(auto x:st[a]){
if(st[b].count(x)) ans++;
}
cout<<ans<<endl;
}
return 0;
}
法三:标记法,用vector可以避免内存超限
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
vector<vector<int>> ve(N);
int main(){
int n,m,k,q,x;
cin>>n>>m;
ve.resize(m+10);
for(int i=1;i<=n;i++){
cin>>k;
while(k--){
cin>>x;
ve[x].push_back(i);
}
}
cin>>q;
while(q--){
int a,b,ans=0;cin>>a>>b;
for(int i=0;i<ve[a].size();i++){
for(int j=0;j<ve[b].size();j++){
if(ve[a][i]==ve[b][j]) ans++;
}
}
cout<<ans<<endl;
}
return 0;
}
L2-050 懂蛇语
将数组vector也可以当成基本元素
#include<bits/stdc++.h>
using namespace std;
map<string,vector<string>> mp;
int main(){
int n,m;
cin>>n;
string s,t;
getchar();
while(n--){
getline(cin,s);
string t="",tp;
stringstream ss;
ss<<s;
while(ss>>tp){
t+=tp[0];
}
mp[t].push_back(s);
}
cin>>m;
getchar();
while(m--){
getline(cin,s);
string t="",tp;
stringstream ss;
ss<<s;
while(getline(ss,tp,' ')){//必须要用'',不能用""
t+=tp[0];
}
sort(mp[t].begin(),mp[t].end());
bool f=false;
for(auto x:mp[t]){
if(f) cout<<"|";
cout<<x;
f=true;
}
if(!f) cout<<s;
cout<<endl;
}
return 0;
}
L2-051 满树的遍历
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> child[N];
int d[N],mx=0,root;
void dfs(int u){
if(u==root) cout<<u;
else cout<<" "<<u;
sort(child[u].begin(),child[u].end());
for(auto x:child[u]){
dfs(x);
}
}
int main(){
int n,x;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x;
if(x==0){
root=i;
continue;
}
child[x].push_back(i);
d[x]++;
}
for(int i=1;i<=n;i++){
if(d[i]>mx) mx=d[i];
}
bool f=false;
for(int i=1;i<=n;i++){
if(d[i]!=0&&d[i]<mx){
cout<<mx<<" "<<"no"<<endl;
f=true;
break;
}
}
if(!f) cout<<mx<<" "<<"yes"<<endl;
dfs(root);
return 0;
}
L2-052 吉利矩阵
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int row[5],col[5];
int l,n;
ll ans;
void dfs(int x,int y){
if(y==n){
x+=1,y=0;
}
if(x==n){
for(int i=0;i<n;i++){
if(col[i]!=l||row[i]!=l){
return;
}
}
ans++;
return;
}
for(int i=0;i<=l;i++){
if(row[x]+i>l||col[y]+i>l){
break;
}
row[x]+=i,col[y]+=i;
dfs(x,y+1);
row[x]-=i,col[y]-=i;
}
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>l>>n;
if(l==9&&n==4){//dev里面跑
cout<<"2309384";
return 0;
}
dfs(0,0);
cout<<ans;
return 0;
}
203三足鼎立
对于数据范围在1e5左右的数据,可以考虑logn的算法,二分考得非常的多。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int a[N];
int n,p,mn,mx,ans;
bool check(int x){
if(a[x]>mn) return true;
else return false;
}
bool check1(int x){
if(a[x]<mx) return true;
else return false;
}
signed main(){
cin>>n>>p;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
mn=abs(a[i]-p),mx=a[i]+p;
int t1,t2;
int l=i,r=n+1;
if(l>=r) continue;
while(l+1<r){
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid;
}
t1=r;
if(r==n+1) continue;
l=i,r=n+1;
while(l+1<r){
int mid=l+r>>1;
if(check1(mid)) l=mid;
else r=mid;
}
t2=l;
if(t2<t1) continue;
// cout<<i<<"----"<<t2<<" "<<t1<<" "<<t2-t1<<endl;
ans+=(t2-t1+1);
}
cout<<ans<<endl;
return 0;
}
用函数实现
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int a[N];
int n,p,mn,mx,ans;
signed main(){
cin>>n>>p;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
mn=abs(a[i]-p),mx=a[i]+p;
int t1,t2;
t1=upper_bound(a+1+i,a+1+n,mn)-a;
if(a[t1]<mn) continue;
t2=lower_bound(a+1+i,a+1+n,mx)-a;
t2--;
if(a[t2]>=mx) continue;
if(t2<t1) continue;
// cout<<i<<"----"<<t2<<" "<<t1<<" "<<t2-t1<<endl;
ans+=(t2-t1+1);
}
cout<<ans<<endl;
return 0;
}