【ACUMTB团队赛】第一周题解

周赛地址:https://vjudge.net/contest/152769#overview

 

A题:

题意:Nikita想选择两门课A和B,使得他想要选的所有学位能被这两门课划分成4个集合,分别是:有AB,有B没A,有A没B,没AB的,并求出这些集合的最大值的最小值。

思路:xjb模拟,才1e6的操作量……

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 const int maxn=105;
 8 
 9 int mp[maxn][maxn];
10 
11 int main()
12 {
13     int mx=0x7fffffff;
14     int n,m;
15     scanf("%d %d",&n,&m);
16     for(int i=1;i<=n;i++){
17         for(int j=1;j<=m;j++){
18             scanf("%d",&mp[i][j]);
19         }
20     }
21     int u=0,v=0;
22     for(int i=1;i<=m;i++){
23         for(int j=i+1;j<=m;j++){
24             int a=0,b=0,c=0,d=0;
25             for(int k=1;k<=n;k++){
26                 if(mp[k][j]==0&&mp[k][j]==mp[k][i]) a++;
27                 else if(mp[k][j]==1&&mp[k][j]==mp[k][i]) b++;
28                 else if(mp[k][j]==0&&mp[k][i]==1) c++;
29                 else if(mp[k][j]==1&&mp[k][i]==0) d++;
30             }
31             int tem=max(a,max(b,max(c,d)));
32             if(mx>tem){
33                 mx=tem;
34                 u=i,v=j;
35             }
36         }
37     }
38     printf("%d\n",mx);
39     printf("%d %d",u,v);
40     return 0;
41 }
View Code

 

B题:

题意:给出起始天和结束天,每ki天(i=2,3……)会作报告,作报告的天会被去掉,剩下的天按照k递增的顺序作报告,问剩下的天数为多少。

思路:按要求玩就行,不理解的话用vector模拟一下就行。

 1 #include<iostream>
 2 using namespace std;
 3 int main()
 4 {
 5     int l,r,i=2;
 6     cin>>l>>r;
 7     while(r/i)
 8     {
 9         r=r-r/i;
10         i++;
11     }
12     i=2;
13     l--;
14     while(l/i)
15     {
16         l=l-l/i;
17         i++;
18     }
19     cout<<r-l<<endl;
20     return 0;
21 }
View Code

 

C题:

题意:n点m边的无向图,求1到n的次短路(最短路可能不止一条,但次短路必须是小于最短路的那条)。

思路:次短路的求法:到v点的最短路记为d[0][v],次短路记为d[1][v],按照Dijkstra的方法进行松弛,①如果d[0][v]>d[now.pos][now.t]+now.w,则先更新d[1][v]=d[0][v],再执行松弛操作,并且将两点的状态放入优先队列中。②如果d[1][v]>d[now.pos][now.t]+now.w,则进行松弛操作,将点的状态放入优先队列中。

由于此题最短路不唯一,在进行②时需要判断v是否为n且d[0][v]==d[now.pos][now.t]+now.w,如果成立则不进行松弛。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <queue>
 4 #include <cstring>
 5 #include <vector>
 6 #include <functional>
 7 
 8 using namespace std;
 9 
10 const int maxn=5005;
11 const int inf=1e9;
12 
13 typedef pair<int,int> P;
14 
15 vector<P> G[maxn];
16 
17 struct node{
18     int t,v,pos;
19     bool operator <(const node&a)const{
20         return v>a.v;
21     }
22 };
23 
24 int n,m;
25 
26 int d[2][maxn];
27 int cou[2][maxn];
28 
29 void init(){
30     for(int i=0;i<maxn;i++){
31         G[i].clear();
32         d[0][i]=d[1][i]=inf;
33     }
34 }
35 
36 void dijkstra(int s){
37     priority_queue<node> q;
38     q.push((node){s,0,0});
39     d[0][s]=0;
40     while(!q.empty()){
41         node now=q.top();
42         q.pop();
43         for(int i=0;i<G[now.t].size();i++){
44             int v=G[now.t][i].first;
45             int dis=G[now.t][i].second;
46             if(d[0][v]>d[now.pos][now.t]+dis){
47                 d[1][v]=d[0][v];
48                 d[0][v]=d[now.pos][now.t]+dis;
49                 q.push((node){v,d[1][v],1});
50                 q.push((node){v,d[0][v],0});
51             }
52             else if(d[1][v]>d[now.pos][now.t]+dis){
53                 if(v==n&&d[0][v]==d[now.pos][now.t]+dis) continue;
54                 d[1][v]=d[now.pos][now.t]+dis;
55                 q.push((node){v,d[1][v],1});
56             }
57         }
58     }
59 }
60 
61 int main(){
62     ios::sync_with_stdio(false);
63     cin.tie(0);
64     int T;
65     cin>>T;
66     int cou=0;
67     while(T--){
68         init();
69         cin>>n>>m;
70         for(int i=0;i<m;i++){
71             int s,t,e;
72             cin>>s>>t>>e;
73             G[s].push_back(P(t,e));
74             G[t].push_back(P(s,e));
75         }
76         dijkstra(1);
77         cout<<"Case "<<++cou<<": "<<d[1][n]<<endl;
78     }
79     return 0;
80 }
View Code

 

D题:

题意:在规定时间内,保证唱最多的歌的情况下,时间唱到最长(所有歌的时间<180s,劲歌金曲678s)

思路:01背包变形,dp[i]为唱时间<=i的歌的数目,最后遍历一遍找最大的dp[i],i为时间的最大值,记得留1s给劲歌金曲。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 
 6 using namespace std;
 7 
 8 const int maxn=11000;
 9 const int maxs=55;
10 
11 int dp[maxn];
12 int a[maxs];
13 
14 int main(){
15     int T,cou=0;
16     cin>>T;
17     while(T--){
18         int n,t;
19         cin>>n>>t;
20         memset(dp,-1,sizeof(dp));
21         for(int i=1;i<=n;i++){
22             cin>>a[i];
23         }
24         dp[0]=0;
25         for(int i=1;i<=n;i++){
26             for(int j=t-1;j>=a[i];j--){
27                 dp[j]=max(dp[j],dp[j-a[i]]+1);
28             }
29         }
30         int ans=t-1;
31         for(int i=t-1;i>=0;i--) if(dp[i]>dp[ans]) ans=i;
32         cout<<"Case "<<++cou<<": "<<dp[ans]+1<<" "<<ans+678<<endl;
33     }
34     return 0;
35 }
View Code

 

E题:

题意:给你n个数m组操作,每组操作有两种:1 x 将1到x的数变为升序排列,2 x 将1到x数变为降序排列,求最后的序列。

思路:单调栈。对于操作i,j(1<=i<j),当xj>xi时,在xi<s<xj的部分,j操作不被影响,1<s<xi的部分,i操作被替换成j操作,所以建立一个单调递减栈,从前向后遍历,最后一组操作单独执行。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 const int maxn=2e5+10;
 8 
 9 typedef pair<int,int> P;
10 
11 P Stack[maxn];
12 
13 int a[maxn],soa[maxn],ans[maxn];
14 
15 int main(){
16     ios::sync_with_stdio(false);
17     cin.tie(0);
18     int n,m;
19     cin>>n>>m;
20     for(int i=1;i<=n;i++){
21         cin>>a[i];
22         soa[i]=a[i];
23     }
24     int p=0;
25     for(int i=0;i<m;i++){
26         int opt,v;
27         cin>>opt>>v;
28         while(p&&Stack[p-1].second<v){
29             p--;
30         }
31         Stack[p++]=P(opt,v);
32     }
33     int st=1,ed=Stack[0].second;
34     sort(soa+1,soa+ed+1);
35     for(int i=n;i>ed;i--){
36         ans[i]=a[i];
37     }
38     for(int i=0;i<p-1;i++){
39         for(int j=Stack[i].second;j>Stack[i+1].second;j--){
40             ans[j]=Stack[i].first==1?soa[ed--]:soa[st++];
41         }
42     }
43     for(int i=Stack[p-1].second;i>=1;i--){
44         ans[i]=Stack[p-1].first==1?soa[ed--]:soa[st++];
45     }
46     for(int i=1;i<=n;i++){
47         cout<<ans[i]<<" ";
48     }
49     return 0;
50 }
View Code

 

posted @ 2017-03-06 20:05  hymscoty  阅读(171)  评论(0编辑  收藏  举报