1. 程式人生 > >多校01_補題記錄

多校01_補題記錄

algorithm cin 如果 只需要 子串 情況 調整 spa esp

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

多校01_補題記錄