多校01_补题记录

1001

题意:int n ,存在x,y,z∈int,满足x+y+z=n,s.t. x*y*z取到最大值,求最大值

最早是用猜的...3的倍数显而易见,试了前20个发现凡4的倍数都能拆成1 1 2的倍数之和..._(:з」∠)_...

正经解法:

   令r=n/x ,s=n/y ,t=n/z ,则 n/r+n/s+n/t=n ,即1/r+1/s+1/t=1

  求解可得(3,3,3),(2,4,4),(2,3,6)三种情况,即3|n or 4|n

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3
 4 using namespace std;
 5 int T,n;
 6
 7 int main(){
 8     long long t,ans;
 9
10     scanf("%d",&T);
11     while(T--){
12         scanf("%d",&n);
13         t=0;
14         if(n%3==0){
15             t=n/3;
16             ans=t*t*t;
17             printf("%lld\n",ans);
18         }
19         else if(n%4==0){
20             int a;
21             t=n/4;
22             ans=t*t*(2*t);
23             printf("%lld\n",ans);
24         }
25         else printf("-1\n");
26     }
27     return 0;
28 } 

1001

1002

题意:给n个由左右小括号组成的字符串,调整字符串间的顺序使得连成的长字符串的Balanced Sequence长度最长(不要求连续),求最长长度

思路:先求每个字符串内的平衡串长度,再对字符串中不在平衡串内的括号组成的子串进行排序(贪心)计算排序后的新的平衡串长度,两部分长度之和为题目所要求的长度

  贪心思路:上述第二部分的子串只有三种可能:只有 ‘(’ ;只有 ‘)‘ ;或者x个 ‘)‘ 连y个 ‘(‘ 。因此只需要对第三种情况进行排序,具体思路详见代码备注

AC代码:

//AC
//重点在于给每个字符串中余下的括号进行排序,cmp改到快死掉.....如果不是有数据...我已经去世了....
//1.贪心:对于同时具有左右括号的部分,
//        把左括号多、右括号少的放前面,尽量少的抵消左括号确保后续更多的右括号能尽可能消去
//2.排序:先处理都大于0的情况,然后处理其一大于0,最后才是全小于0,顺序不能变
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<algorithm>

using namespace std;
int t,n;
int tagl,tagr,ans;
char s[100005];
stack<char>st;
struct node{
    int l,r;
}a[100005];
bool cmp(node x,node y){       //注意比较的顺序!!!
    if(x.l+x.r>=0&&y.l+y.r>=0) return x.r>y.r;
    if(x.l+x.r>=0||y.l+y.r>=0)return x.l+x.r>y.l+y.r;
    if(x.l+x.r<=0&&y.l+y.r<=0) return x.l>y.l;
}

int main(){
//    freopen("1002.in", "r", stdin);
//   freopen("1002t.out", "w", stdout);
    cin>>t;
    while(t--){
        cin>>n;
        tagl=tagr=0;
        int k=0;
        ans=0;
        for(int i=0;i<n;i++){
            cin>>s;
            int len=strlen(s);
            for(int j=0;j<len;j++){
                if(s[j]==‘(‘)
                    st.push(s[j]);
                else{
                    if(!st.empty()&&st.top()==‘(‘){
                        ans++;st.pop();
                    }
                    else st.push(s[j]);
                }
            }
                        int ll=0,rr=0;
            while(!st.empty()){
                if(st.top()==‘(‘) ll++;
                else rr--;
                st.pop();
            }
            if(ll==0||rr==0){
                tagl+=ll;tagr+=rr;
            }
            else{
                a[k].l=ll;a[k].r=rr; k++;
            }
        }

        sort(a,a+k,cmp);
        for(int i=0;i<k;i++){
            if(tagl<0) tagl=0;
            if(tagl+a[i].r<0){
                ans+=tagl;
                tagl=a[i].l;
            }
            else{
                ans-=a[i].r;
                tagl+=a[i].r+a[i].l;
            }
        }
        ans+=min(-tagr,tagl);
        cout<<2*ans<<endl;

    }
}            

1002

1003

题意:给3n个点,保证不存在三点共线的情况,输出任一种组成n个不相交三角形的情况

思路:所有点坐标按x轴排序,然后顺序输出,over

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;
int t,n,np;
struct node{
    int num;
    int x,y;
}tri[3005];
bool cmp(node a,node b){
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

int main(){
    cin>>t;
    while(t--){
        cin>>n;
        np=3*n;
        for(int i=0;i<np;i++){
            cin>>tri[i].x>>tri[i].y;
            tri[i].num=i+1;
        }
        sort(tri,tri+np,cmp);
        for(int i=0;i<np;){
            cout<<tri[i].num<<" "<<tri[i+1].num<<" "<<tri[i+2].num<<endl;
            i=i+3;
        }
    }
}

1003

1004

题意:有一个长度为n的数组,已知几个事实:给定闭区间范围内的数互不相等,求满足事实的最小字典序数组

思路:对区间排序,对任意点可得到覆盖该点的最大区间。最小字典序数组意味着从第一个位置开始往后每个位置取当前满足条件的最小值,用set储存当前可以使用的数,在某一闭区间范围内使用一个删一个,flag标记上一次开始删除元素的位置,遇到新的区间时将flag->区间左端点的范围内的数字加入set

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>

using namespace std;
int t,n,m,ans[100005];
struct node{
    int st,ed;
}a[100005];
bool cmp(node x,node y){
    if(x.st!=y.st) return x.st<y.st;
    return x.ed>y.ed;
}
set<int> s;

int main(){
    cin>>t;
    while(t--){
        s.clear();
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            s.insert(i);
        }
        for(int i=0;i<m;i++){
            cin>>a[i].st>>a[i].ed;
        }
        sort(a,a+m,cmp);      

        int k=1,flag=1;
        for(int i=0;i<m;i++){
            if(k<a[i].st){
                while(k<a[i].st){
                    ans[k]=1;k++;
                }
                while(flag<a[i].st){
                    s.insert(ans[flag]);
                    flag++;
                }
                while(k<=a[i].ed){
                    ans[k]=(*s.begin());
                    k++;
                    s.erase(*s.begin());
                }
            }
            else if(k>a[i].ed){
                continue;
            }
            else{
                while(flag<a[i].st){
                    s.insert(ans[flag]);
                    flag++;
                }
                while(k<=a[i].ed){
                    ans[k]=(*s.begin());
                    s.erase(*s.begin());
                    k++;
                }
            }
        }
        while(k<=n) ans[k++]=1;    

        cout<<ans[1];
        for(int i=2;i<=n;i++)cout<<" "<<ans[i];
        cout<<endl;
    }
}

1004

1011

题意:求北京时间在给定时区的当地时间

思路:模拟

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
int t,a,b,h,m,xh,xm;
char s[10];

int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&a,&b);
        scanf("%s",&s);
        int len=strlen(s);
        int i=4;
        xh=0;
        xm=0;
        while(s[i]!=‘.‘){
            xh=xh*10+(s[i]-‘0‘);
            i++;
            if(i>=len) break;
        }
        if(s[len-2]==‘.‘) xm=(s[len-1]-‘0‘)*6;
        if(s[3]==‘-‘) {
            xh=xh*(-1);
            xm=xm*(-1);
        }

        h=a+(xh-8);
        m=b+xm;
        if(m>=60) {h++;m=m-60;}
        else if(m<0){h--;m=60+m;}
        if(h>=24){h=h-24;}
        else if(h<0){h=24+h;}          

        printf("%02d:%02d\n",h,m);

    }
}

1011

原文地址:https://www.cnblogs.com/anonym/p/9363119.html

时间: 2024-08-30 18:36:21

多校01_补题记录的相关文章

[2015hdu多校联赛补题]hdu5371 Hotaru&#39;s problem

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5371 题意:把一个数字串A翻过来(abc翻过来为cba)的操作为-A,我们称A-AA这样的串为N-sequence,现在给你一个数字串,问你这个串中最长的N-sequence子串长度 解:可以想到A-A是一个回文串,-AA也是一个回文串,那么首先Manacher跑一遍求出所有回文子串 可以想到任意两个互相覆盖的回文子串都可以表示成N-sequence 然后有三种搞法: 1.时间复杂度O(N*logN

[2015hdu多校联赛补题]hdu5348 MZL&#39;s endless loop

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5348 题意:给你一个无向图,要你将无向图的边变成有向边,使得得到的图,出度和入度差的绝对值小于等于1,如果无解输出-1 解:考虑奇数度的点一定会成对出现(因为所有度数和肯定是偶数个->因为一条边产生两度~),那么我们可以将奇数度的点两两一连消除掉(两奇数度点的出度入读差的绝对值都为1, 路径上的点的差绝对值为0) 然后偶数度的点可以成环,那么可以搜出所有的环 1 /* 2 * Problem: 3

[水]浙大校赛补题

本来以为会巨难无比又有别的比赛可以打于是赛后补题,结果发现似乎略水,反正是找到了四个水题先贴下来 ZOJ-4099 J #include<iostream> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; int t; ll x, y, n; int main() { cin >> t; while (t--) { scanf("%lld

[2015hdu多校联赛补题]hdu5293 Tree chain problem

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意:给你一棵n个点的树,和一些该树上的树链,每个树链有一定的权值,要求选出一些不相交的树链,使他们的权值和尽量大 解: 树形dp,dp[x]表示以x为根节点的子树的解,那么就可以基于在当前结点对树链的选和不选进行dp 现在有两个问题: 1.在树链上的哪个点进行选择? 2.选和不选分别如何操作? 对于第一个问题,粗略想一下(在解决问题二的时候会发现),树链上最浅的一个点(也就是树链两端的lca

[2015hdu多校联赛补题]hdu5302 Connect the Graph

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5302 题意:给你一个无向图,它的边要么是黑色要么是白色,且图上的每个点最多与两个黑边两个白边相连.现在,Demon将图分成两部分,一部分包含所有的黑边,另一部分包括所有的白边,给你白边图中度为0的点的数量w0,度为1的点数w1,度为2的点数w2,与黑边图中度为0的点数b1,度为1的点数b1,度为2的点数b2,要你输出任意一个符合条件的原图,如果不能,输出-1 (注1:无论是黑边图,还是白边图,给出的

[2015hdu多校联赛补题]hdu5384 Danganronpa

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384 题意:函数f(A, B)定义:A.B为字符串,f(A, B)为A中有多少个不同的B(ex:f("ababa", "aba")==2   f("ababa", "bab")==1),现在给你一组A串,一组B串,问你对每个A串的是多少 解:ac自动机模板题,可以把A串用'z'+1,连成一个串处理起来比较方便 1 /* 2 * P

Codeforces 补题记录

首先总结一下前段时间遇到过的一些有意思的题. Round #474 (Div. 1 + Div. 2, combined)   Problem G 其实关键就是n这个数在排列中的位置. 这样对于一个排列,设$f[pos] = p$, 那么从位置$1$到位置$pos$最大值被刷新了$a$次,从位置$n$到位置$pos$最大值被刷新了$b$次. 去掉$n$之后,剩下$n-1$个数被分成了两个部分. 假设把这$n-1$个数分成$a+b-2$个组,分配给左边$a-1$个组,给右边$b-1$个组. 对于$

Codeforces Round #617 (Div. 3) 补题记录

1296A - Array with Odd Sum 题意:可以改变数组中的一个数的值成另外一个数组中的数,问能不能使数组的和是个奇数 思路:签到,如果本来数组的和就是个奇数,那就OK 如果不是,就需要把数组中其中一个奇(偶)数改成偶(奇)数,相当于加一减一 所以测一下这个数组如果有个奇数并且还有个偶数就行 #include <cstdio> #include <iostream> #include <map> #include <set> #include

[2015hdu多校联赛补题]hdu5378 Leader in Tree Land

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5378 题意:给你一棵n个结点的有根树.因为是有根树,那么每个结点可以指定以它为根的子树(后面讨论的子树都是这个).现在我们把标号从1到n的n个minister派驻到这些结点上面(每个结点派驻一人),并规定任一子树中编号最大的minister 为该子树的领导,问你存在多少个不同的领导 解: 引用官方题解: 可以用求概率的思想来解决这个问题.令以i号节点为根的子树为第i棵子树,设这颗子树恰好有sz[i]