2018 Multi-University Training Contest 1

本文解析了HDU ACM平台上的多个编程题目,包括求解数字组合的最大乘积、平衡字符串配对、三角形分区及数值破坏等,通过算法分析提供了详细的解题思路与代码实现。

orz,学弟还没有来。

 

A.Maximum Multiple

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6298

题意:给一个数字n,满足下面几个式子:n=x+y+z,n%x==0,n%y==0,n%z==0,求xyz的乘积最大值。

分析:设n=ax,n=by,n=cz,得1/a+1/b+1/c=1,所以答案就是n3/(abc)。(令abc越小越好)又可以知道:

所以,就是三种情况。(实际上只有两种,可以被整除2,3,6,那么一定可以被3,3,3整除)

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 int main(){
 7     ios::sync_with_stdio(false);
 8     cin.tie(0);cout.tie(0);
 9     int t,n;
10     ll x1=2*3*6,x2=3*3*3,x3=2*4*4;
11     cin >> t;
12     while (t--){
13         cin >> n;
14         ll xx=1ll*n*n*n;
15         if (xx%x2==0){
16             cout << xx/x2 << endl;
17             continue;;
18         }
19         if (xx%x3==0){
20             cout << xx/x3 << endl;
21             continue;
22         }
23         if (xx%x1==0){
24             cout << xx/x1 << endl;
25             continue;
26         }
27         cout << -1 << endl;
28     }
29     return 0;
30 }
hdoj6298

PS.其中n*n*n的过程中需要转化成ll,否则wa。

 

B.Balanced Sequence

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6299

题意:若干个字符串,只包含'(',')',随意组合,问有多少左右括号可以组合成功。

分析:首先可以对字符串进行处理,将已经有的左右括号抵消掉,直接加到答案里。剩下的串每个可以表示为若干个')'和若干个'('组成的串,只需要考虑将剩下的这些串进行组合。那么可以表示为每个串有l个')'和r个‘(’,排序贪心就好。(可以多个串拼接)

排序顺序为,l短r长的在前,l长r短的在后。

dls说不会排序就随便拍,23333总会对的。(对面大佬随便写了4中排序取最优答案就过了23333

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<stack>
 5 #define maxn 100005
 6 using namespace std;
 7 int n;
 8 struct point{
 9     int l,r;
10     int id;
11 }a[maxn];
12 int ans;
13 void init(string ss,int k){
14     char S[maxn];
15     int top=0;
16     int len=ss.length();
17     for (int i=0;i<len;i++){
18         if (ss[i]==')'){
19             if (S[top-1]=='('){
20                 ans+=2;
21                 top--;
22             }
23             else S[top++]=ss[i];
24         }
25         else{
26             S[top++]=ss[i];
27         }
28     }
29     int i;
30     for (i=0;i<top;i++){
31         if (S[i]=='(') break;
32     }
33     a[k].l=i;a[k].r=top-i;
34     return ;
35 }
36 
37 int comp(point p,point q){
38     if (p.l<p.r && q.l>=q.r) return 1;
39     if (p.l>=p.r && q.l<q.r) return 0;
40     if (p.l<p.r && q.l<q.r){
41         return p.l<q.l;
42     }
43     if (p.l>=p.r && q.l>=q.r){
44         return p.r>q.r;
45     }
46 }
47 int main(){
48     ios::sync_with_stdio(false);
49     cin.tie(0);cout.tie(0);
50     int t;
51     string ss;
52     cin >> t;
53     while (t--){
54         cin >> n;
55         ans=0;
56         for (int i=0;i<n;i++){
57             cin >> ss;
58             init(ss,i);
59             a[i].id=i+1;
60         }
61         sort(a,a+n,comp);
62         //for (int i=0;i<n;i++) cout << a[i].id << endl;
63         int ll=a[0].l,rr=a[0].r;
64         for (int i=1;i<n;i++){
65             int xx=min(rr,a[i].l);
66             rr=rr-xx+a[i].r;
67             ll=ll+(a[i].l-xx);
68             ans+=xx*2;
69         }
70         cout << ans << endl;
71     }
72     return 0;
73 } 
hdoj6299

 

C.Triangle Partition

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6300

题意:3n个点组成n个三角形。输出任一种方案。spj

分析:排序。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define maxn 3005
 5 using namespace std;
 6 struct point{
 7     int x,y;
 8     int id;
 9 }a[maxn];
10 int comp(point p,point q){
11     return p.x<q.x || p.x==q.x && p.y<q.y;
12 } 
13 int main(){
14     ios::sync_with_stdio(false);
15     cin.tie(0);cout.tie(0);
16     int t,n;
17     cin >> t;
18     while (t--){
19         cin >> n;
20         for (int i=1;i<=3*n;i++){
21             cin >> a[i].x >> a[i].y;
22             a[i].id=i;
23         }
24         sort(a+1,a+1+3*n,comp);
25         for (int i=1;i<=3*n;i+=3){
26             cout << a[i].id << " " << a[i+1].id << " " << a[i+2].id << endl;
27         }
28     }
29     return 0;
30 }
hdoj6300

 

D.Distruct Values

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6301

题意:n个数,m个条件,每个条件为区间[l,r]内数字不能相同。要求求出字典序最小的n个数。

分析:首先将区间处理,包含在内的区间去除掉。然后贪心做法,将所有数放在set内,用一个擦掉一个。当发现可以重新添加的时候,重新插入即可。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<set>
 5 #define maxn 100005
 6 using namespace std;
 7 int pre[maxn],ret[maxn];
 8 int n,m;
 9 int main(){
10     ios::sync_with_stdio(false);
11     cin.tie(0);cout.tie(0);
12     int t,l,r;
13     cin >> t;
14     while (t--){
15         cin >> n >> m;
16         for (int i=1;i<=n;i++) pre[i]=i;
17         for (int i=0;i<m;i++){
18             cin >> l >> r;
19             pre[r]=min(pre[r],l);
20         }
21         for (int i=n-1;i>=1;i--){
22             pre[i]=min(pre[i],pre[i+1]);
23         }
24         int pl=1;
25         set<int> val;
26         for (int i=1;i<=n;i++) val.insert(i);
27         for (int i=1;i<=n;i++){
28             while (pl<pre[i]){
29                 val.insert(ret[pl]);
30                 pl++;
31             }
32             ret[i]=*val.begin();
33             val.erase(ret[i]);
34         }
35         for (int i=1;i<n;i++)
36             cout << ret[i] << " ";
37         cout << ret[n] << endl;
38     }    
39     return 0;
40 }
hdoj6301

 

 

K.Time Zone

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6308

题意:给出北京时区(UTC+8)的时间,求任一时区的时间。

分析:如题。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<string>
 4 using namespace std;
 5 int a,b;
 6 string ss;
 7 int main(){
 8     ios::sync_with_stdio(false);
 9     cin.tie(0);cout.tie(0);
10     int t,flag;
11     cin >> t;
12     while (t--){
13         cin >>a>>b;
14         int a1=a-8;if (a1<=0) a1+=24;  //UTC+0 
15         int b1=b;//计算出现在的时间UTC0的时间 
16         cin >> ss;
17         int len=ss.length();
18         if (ss[3]=='+') flag=1;
19         else flag=0;//判断是加还是减 
20         int numh=0,numm=0;
21         int i;
22         for (i=4;i<len;i++){
23             if (ss[i]=='.') break;
24             numh=numh*10+(ss[i]-'0');
25         }
26         if (i<len) numm=(ss[i+1]-'0')*6;
27         int ansa,ansb; 
28         if (flag){
29             ansa=a1+numh;
30             ansb=b1+numm;
31             if (ansb>=60){
32                 ansb-=60;
33                 ansa++;
34             }
35             if (ansa>=24){
36                 ansa-=24;
37             }
38             if (ansb<0){
39                 ansb+=60;
40                 ansa--;
41             }
42             if (ansa<0){
43                 ansa+=24;
44             }
45         } 
46         if (!flag){
47             ansa=a1-numh;
48             ansb=b1-numm; 
49             if (ansb<0){
50                 ansb+=60;
51                 ansa--;
52             }
53             if (ansa<0){
54                 ansa+=24;
55             }
56             if (ansb>=60){
57                 ansb-=60;
58                 ansa++;
59             }
60             if (ansa>=24){
61                 ansa-=24;
62             }
63         }
64         
65         if (ansa/10==0){
66             cout << "0";
67         }
68         cout << ansa << ":"; 
69         if (ansb/10==0){
70             cout << "0";
71         }
72         cout << ansb << endl;
73     }
74     return 0;
75 }
hdoj6308

 

转载于:https://www.cnblogs.com/changer-qyz/p/9359777.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值