牛客小白月赛6

https://www.nowcoder.com/acm/contest/136#question

所有代码:

https://pan.baidu.com/s/1B0a4CZ6HFev0iwDdtDwBcA

 

A.

好题

 

C.

树最长链

两种方法

 

 1 /**
 2 同样的遍历,若无特殊要求,用bfs!
 3 dfs要保存、返回函数中间状态,
 4 dfs比bfs慢不少,如一棵有很多分叉的树。
 5 
 6 题解的方法
 7 */
 8 
 9 #include 
10 #include 
11 #include 
12 #include 
13 #include 
14 #include <string>
15 #include <set>
16 #include 
17 #include 
18 #include 
19 #include 
20 #include 
21 #include 
22 #include 
23 #include 
24 #include 
25 using namespace std;
26 #define ll long long
27 #define minv 1e-6
28 #define inf 1e9
29 #define pi 3.1415926536
30 #define E  2.7182818284
31 const ll mod=1e9+7;//998244353
32 const int maxn=1e6+10;
33 
34 struct node
35 {
36     int d;
37     node* next;
38 }*e[maxn],*p;
39 
40 int q[maxn],l[maxn];
41 bool vis[maxn];
42 int head,tail;
43 
44 void bfs(int d)
45 {
46     head=0,tail=1;
47     q[1]=d,l[1]=1;
48     memset(vis,0,sizeof(vis));
49     while (head<tail)
50     {
51         head++;
52         p=e[ q[head] ];
53         while (p)
54         {
55             if (!vis[p->d])
56             {
57                 vis[p->d]=1;
58                 tail++;
59                 q[tail]=p->d;
60                 l[tail]=l[head]+1;
61             }
62             p=p->next;
63         }
64     }
65 }
66 
67 int main()
68 {
69     int n,i,x,y;
70     scanf("%d",&n);
71     for (i=1;i<=n;i++)
72         e[i]=NULL;
73     for (i=1;i)
74     {
75         scanf("%d%d",&x,&y);
76         p=(node*) malloc (sizeof(node*));
77         p->d=y;
78         p->next=e[x];
79         e[x]=p;
80 
81         p=(node*) malloc (sizeof(node*));
82         p->d=x;
83         p->next=e[y];
84         e[y]=p;
85     }
86     bfs(1);
87     bfs(q[tail]);
88     printf("%d",l[tail]);
89 
90     return 0;
91 }

 

  1 /*
  2 dp
  3 */
  4 #include 
  5 #include 
  6 #include 
  7 #include 
  8 #include 
  9 #include <string>
 10 #include <set>
 11 #include 
 12 #include 
 13 #include 
 14 #include 
 15 #include 
 16 #include 
 17 #include 
 18 #include 
 19 #include 
 20 using namespace std;
 21 #define ll long long
 22 #define minv 1e-6
 23 #define inf 1e9
 24 #define pi 3.1415926536
 25 #define E  2.7182818284
 26 const ll mod=1e9+7;//998244353
 27 const int maxn=1000000+10;
 28 
 29 //用vector比用node稍微慢一点,但是也许vector更方便
 30 
 31 struct node
 32 {
 33     int d;
 34     node* next;
 35 }*point[maxn];
 36 
 37 //vectore[maxn];
 38 bool vis[maxn]={0};
 39 int r;
 40 
 41 //返回的是目前以d为根节点(之后会变)的最长链
 42 int dfs(int d)
 43 {
 44     int value=0,v1=0,v2=0,v;
 45     int dd;
 46     node* p;
 47 //    vector::iterator i;
 48     vis[d]=1;
 49 //    for (i=e[d].begin();i!=e[d].end();i++)
 50     p=point[d];
 51     while (p)
 52     {
 53 //        dd=*i;
 54         dd=p->d;
 55         if (!vis[dd])
 56         {
 57             v=dfs(dd);
 58             value=max(value,v);
 59             if (v>v1)
 60             {
 61                 v2=max(v1,v2);
 62                 v1=v;
 63             }
 64             else if (v>v2)
 65                 v2=v;
 66         }
 67         p=p->next;
 68     }
 69     //d为根节点,左右各连接一条链,即求以d儿子为根节点的最长的两条链
 70     r=max(r,v1+v2+1);
 71     return value+1;
 72 }
 73 
 74 int main()
 75 {
 76     int n,x,y,i;
 77     node* p;
 78     scanf("%d",&n);
 79     for (i=1;i<=n;i++)
 80         point[i]=NULL;
 81     for (i=1;i)
 82     {
 83         scanf("%d%d",&x,&y);
 84         p=(struct node *) malloc (sizeof(node));
 85         p->d=y;
 86         p->next=point[x];
 87         point[x]=p;
 88 
 89         p=(struct node *) malloc (sizeof(node));
 90         p->d=x;
 91         p->next=point[y];
 92         point[y]=p;
 93 //        e[x].push_back(y);
 94 //        e[y].push_back(x);
 95     }
 96     i=dfs(1);
 97     printf("%d",r);
 98     return 0;
 99 }
100 /*
101 4
102 1 2
103 1 3
104 1 4
105 */

 

 

vector

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include <string>
 7 #include <set>
 8 #include 
 9 #include 
10 #include 
11 #include 
12 #include 
13 #include 
14 #include 
15 #include 
16 #include 
17 using namespace std;
18 #define ll long long
19 #define minv 1e-6
20 #define inf 1e9
21 #define pi 3.1415926536
22 #define E  2.7182818284
23 const ll mod=1e9+7;//998244353
24 const int maxn=1e6+10;
25 
26 vector<int>st;
27 char mode[10];
28 
29 /*
30 注意对于存在的指纹,相邻指纹距离>k
31 对于一个数x,只有指纹中大于等于x的第一个数y 和 该数y的上一个数z 才有可以与x的距离小于等于k
32 */
33 
34 int main()
35 {
36     vector<int>::iterator pos;
37     int m,k,x;
38     scanf("%d%d",&m,&k);
39     while (m--)
40     {
41         scanf("%s%d",mode,&x);
42         if (strcmp(mode,"add")==0)
43         {
44             //lower_bound*(>=)相当于二分,相当方便!!! upper_bound(>)
45             pos=lower_bound(st.begin(),st.end(),x);
46             if ((pos>=st.end() || *pos-x>k) &&
47                 ((st.begin()==st.end() || pos-11)>k))
48                     st.insert(pos,x);
49         }
50         else if (strcmp(mode,"del")==0)
51         {
52             pos=lower_bound(st.begin(),st.end(),x);
53             if (!(pos>=st.end() || *pos-x>k))
54                 st.erase(pos);
55             if (!((st.begin()==st.end() || pos-11)>k))
56                 st.erase(pos-1);
57         }
58         else
59         {
60             pos=lower_bound(st.begin(),st.end(),x);
61             if ((pos>=st.end() || *pos-x>k) &&
62                 ((st.begin()==st.end() || pos-11)>k))
63                     printf("No\n");
64             else
65                     printf("Yes\n");
66         }
67     }
68     return 0;
69 }
70 /*
71 14 1
72 add 1
73 add 3
74 add 5
75 add 7
76 add 9
77 query 2
78 del 2
79 query 2
80 query 8
81 del 8
82 query 8
83 query 6
84 del 5
85 query 5
86 */

 

H.

最小生成树裸题

 1 /*
 2 最小生成树裸题
 3 边少,用Kruskal
 4 */
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 #include 
10 #include <string>
11 #include <set>
12 #include 
13 #include 
14 #include 
15 #include 
16 #include 
17 #include 
18 #include 
19 #include 
20 #include 
21 using namespace std;
22 #define ll long long
23 #define minv 1e-6
24 #define inf 1e9
25 #define pi 3.1415926536
26 #define E  2.7182818284
27 const ll mod=1e9+7;//998244353
28 const int maxn=1e5+10;
29 
30 struct node
31 {
32     int a,b,v;
33 }e[maxn*5];//注意
34 int fa[maxn];
35 
36 int getfather(int d)
37 {
38     if (fa[d]==d)
39         return d;
40     fa[d]=getfather(fa[d]);
41     return fa[d];
42 }
43 
44 int cmp(node a,node b)
45 {
46     return a.v<b.v;
47 }
48 
49 int g=0,b[maxn];
50 
51 int main()
52 {
53     int n,m,i,c=0,x,y,sum=0;
54     scanf("%d%d",&n,&m);
55     for (i=1;i<=n;i++)
56         fa[i]=i;
57     for (i=1;i<=m;i++)
58         scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].v);
59     sort(e+1,e+m+1,cmp);
60     c=n-1;
61     i=0;
62     while (c--)
63     {
64         do
65         {
66             i++;
67             x=getfather(e[i].a);
68             y=getfather(e[i].b);
69         }
70         while (x==y);
71         fa[x]=y;
72         sum+=e[i].v;
73             g++;
74             b[g]=e[i].v;
75     }
76     printf("%d",sum);
77 
78     sort(b+1,b+g+1);
79     printf("\ng=%d\n",g);
80     for (i=1;i<=g;i++)
81         printf("%d\n",b[i]);
82     return 0;
83 }
84 /*
85 4 5
86 1 2 3
87 1 3 1
88 1 2 3
89 2 3 4
90 1 4 5
91 */

 

  1 /*
  2 最小生成树裸题
  3 Prim + 堆优化
  4 */
  5 #include 
  6 #include 
  7 #include 
  8 #include 
  9 #include 
 10 #include <string>
 11 #include <set>
 12 #include 
 13 #include 
 14 #include 
 15 #include 
 16 #include 
 17 #include 
 18 #include 
 19 #include 
 20 #include 
 21 using namespace std;
 22 #define ll long long
 23 #define minv 1e-6
 24 #define inf 1e9
 25 #define pi 3.1415926536
 26 #define E  2.7182818284
 27 const ll mod=1e9+7;//998244353
 28 const int maxn=1e5+10;
 29 
 30 int dist[maxn];
 31 struct rec
 32 {
 33     int d,dist;
 34 };
 35 
 36 struct cmp1
 37 {
 38     bool operator() (rec a,rec b)
 39     {
 40         return a.dist>b.dist; //最小堆 > 而不是 <
 41     }
 42 };
 43 
 44 ///注意,若只用d,不用dist,结果不对!!!
 45 priority_queue,cmp1 >st;
 46 
 47 struct node
 48 {
 49     int d,len;
 50     node* next;
 51 }*e[maxn],*p;
 52 bool vis[maxn]={0};
 53 
 54 int g=0,b[maxn];
 55 
 56 int main()
 57 {
 58     int n,m,i,d,x,y,z,sum=0;
 59     vectorint,int> >::iterator j;
 60     scanf("%d%d",&n,&m);
 61     for (i=1;i<=n;i++)
 62         e[i]=NULL;
 63     for (i=1;i<=m;i++)
 64     {
 65         scanf("%d%d%d",&x,&y,&z);
 66         p=(node*) malloc (sizeof(node));
 67         p->d=y;
 68         p->len=z;
 69         p->next=e[x];
 70         e[x]=p;
 71 
 72         p=(node*) malloc (sizeof(node));
 73         p->d=x;
 74         p->len=z;
 75         p->next=e[y];
 76         e[y]=p;
 77     }
 78     for (i=1;i<=n;i++)
 79         dist[i]=inf;
 80     dist[1]=0;
 81     st.push({1,0});
 82     while (1)
 83     {
 84         while (!st.empty() && vis[st.top().d])
 85             st.pop();
 86         if (st.empty())
 87             break;
 88         d=st.top().d;
 89         st.pop();
 90         vis[d]=1;
 91         sum+=dist[d];
 92         p=e[d];
 93         while (p)
 94         {
 95             if (dist[p->d]>p->len)
 96             {
 97                 dist[p->d]=p->len;
 98                 st.push({p->d,p->len});
 99             }
100             p=p->next;
101         }
102     }
103     printf("%d",sum);
104     return 0;
105 }

 

J.

最短路径裸题

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include <string>
 7 #include <set>
 8 #include 
 9 #include 
10 #include 
11 #include 
12 #include 
13 #include 
14 #include 
15 #include 
16 #include 
17 using namespace std;
18 #define ll long long
19 #define minv 1e-6
20 #define inf 1e9
21 #define pi 3.1415926536
22 #define E  2.7182818284
23 const ll mod=1e9+7;//998244353
24 const int maxn=1e5+10;
25 
26 vectorint,int> >e[maxn];
27 int dist[maxn],q[maxn];
28 bool vis[maxn]={0};
29 
30 int main()
31 {
32     int n,m,d,t,i,x,y,z,head,tail;
33     vectorint,int> >::iterator j;
34     scanf("%d%d%d%d",&n,&m,&d,&t);
35     for (i=1;i<=m;i++)
36     {
37         scanf("%d%d%d",&x,&y,&z);
38         e[x].push_back(make_pair(y,z));
39         e[y].push_back(make_pair(x,z));
40     }
41     for (i=1;i<=n;i++)
42         dist[i]=inf;
43     dist[d]=0;
44     //я╜╩╥╤сап
45     head=0,tail=1;
46     q[1]=d;
47     while (head!=tail)
48     {
49         head=(head+1)%n;
50         d=q[head];
51         for (j=e[d].begin();j!=e[d].end();j++)
52             if (dist[j->first]>dist[d]+j->second)
53             {
54                 dist[j->first]=dist[d]+j->second;
55                 if (!vis[j->first])
56                 {
57                     vis[j->first]=1;
58                     tail=(tail+1)%n;
59                     q[tail]=j->first;
60                 }
61             }
62         vis[d]=0;
63     }
64     if (dist[t]==inf)
65         printf("-1");
66     else
67         printf("%d",dist[t]);
68     return 0;
69 }

 

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include <string>
 7 #include <set>
 8 #include 
 9 #include 
10 #include 
11 #include 
12 #include 
13 #include 
14 #include 
15 #include 
16 #include 
17 using namespace std;
18 #define ll long long
19 #define minv 1e-6
20 #define inf 1e9
21 #define pi 3.1415926536
22 #define E  2.7182818284
23 const ll mod=1e9+7;//998244353
24 const int maxn=1e5+10;
25 
26 struct rec
27 {
28     int d,dist;
29 };
30 
31 struct cmp
32 {
33     bool operator() (rec a,rec b)
34     {
35         return a.dist>b.dist;
36     }
37 };
38 
39 priority_queue,cmp>st;
40 
41 struct node
42 {
43     int d,len;
44     node* next;
45 }*e[maxn],*p;
46 bool vis[maxn]={0};
47 int dist[maxn];
48 
49 int main()
50 {
51     int n,m,d,t,i,x,y,z;
52     scanf("%d%d%d%d",&n,&m,&d,&t);
53     for (i=1;i<=n;i++)
54         e[i]=NULL;
55     for (i=1;i<=m;i++)
56     {
57         scanf("%d%d%d",&x,&y,&z);
58         p=(node*) malloc (sizeof(node));
59         p->d=y;
60         p->len=z;
61         p->next=e[x];
62         e[x]=p;
63 
64         p=(node*) malloc (sizeof(node));
65         p->d=x;
66         p->len=z;
67         p->next=e[y];
68         e[y]=p;
69     }
70     for (i=1;i<=n;i++)
71         dist[i]=inf;
72     dist[d]=0;
73     st.push({d,0});
74     while (d!=t)
75     {
76         while (!st.empty() && vis[st.top().d])
77             st.pop();
78         if (st.empty())
79             break;
80         d=st.top().d;
81         st.pop();
82         p=e[d];
83         while (p)
84         {
85             if (dist[p->d]>dist[d]+p->len)
86             {
87                 dist[p->d]=dist[d]+p->len;
88                 st.push({p->d,dist[p->d]});
89             }
90             p=p->next;
91         }
92     }
93     if (dist[t]==inf)
94         printf("-1");
95     else
96         printf("%d",dist[t]);
97     return 0;
98 }

 

J.

可用矩阵快速幂

牛客小白月赛6_第1张图片

 

 1 /*
 2 t(i)->t(i+1) 一次多元函数 矩阵快速幂是套路
 3 
 4 n个变量和常数,则创建(n+1)*(n+1)的矩阵
 5 t(i+1)=t(i)+f(i)
 6 f(i+1)=f(i)*k+p
 7 见目录图片
 8 */
 9 #include 
10 #include 
11 #include 
12 #include 
13 #include 
14 #include <string>
15 #include <set>
16 #include 
17 #include 
18 #include 
19 #include 
20 #include 
21 #include 
22 #include 
23 #include 
24 #include 
25 using namespace std;
26 #define ll long long
27 #define minv 1e-6
28 #define inf 1e9
29 #define pi 3.1315926536
30 #define E  2.7182818283
31 const ll mod=1e9+7;//998233353
32 const int maxn=1e5+10;
33 
34 //要加{}
35 ll a[3][3]={
36 {1,0,0},
37 {0,0,0},
38 {0,0,1}
39 };
40 ll b[3][3],c[3][3];
41 
42 int main()
43 {
44     int n,i,j,k;
45     ll K,p;
46     scanf("%d%lld%lld",&n,&K,&p);
47     a[0][1]=a[1][1]=K;
48     a[0][2]=a[1][2]=p;
49     for (i=0;i<3;i++)
50         for (j=0;j<3;j++)
51             b[i][j]=(i==j);
52     n--;
53     while (n)
54     {
55         if (n & 1)
56         {
57             for (i=0;i<3;i++)
58                 for (j=0;j<3;j++)
59                     c[i][j]=b[i][j],b[i][j]=0;
60             for (i=0;i<3;i++)
61                 for (j=0;j<3;j++)
62                     for (k=0;k<3;k++)
63                         b[i][j]=(b[i][j]+c[i][k]*a[k][j])%mod;
64         }
65 
66         for (i=0;i<3;i++)
67             for (j=0;j<3;j++)
68                 c[i][j]=a[i][j],a[i][j]=0;
69         for (i=0;i<3;i++)
70             for (j=0;j<3;j++)
71                 for (k=0;k<3;k++)
72                     a[i][j]=(a[i][j]+c[i][k]*c[k][j])%mod;
73         n>>=1;
74     }
75     printf("%lld",(b[0][0]+b[0][1]+b[0][2])%mod);
76     return 0;
77 }

 

转载于:https://www.cnblogs.com/cmyg/p/9520782.html

你可能感兴趣的:(数据结构与算法)