zoukankan      html  css  js  c++  java
  • 2017.10.6北京清北综合强化班DAY6

     

    题目大意:改变一个数的位置 把一个序列变成不下降序列

    题解:

    设置一个pre,如果破坏单调性,就把‘删除’这个。否则把pre修改为当前元素的值。

    考试时这样得了90分,是因为我的做法只能过这样的数据

    1 3 4 1 5 7  (这个序列移动的数字是第二个1)

    不能过这样的

    1 3 6 100 7 9 10 (这个序列按我的做法移动的是7,但是应该是移去100)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1000009
    using namespace std;
    
    int n,pre,tot,a[maxn];
    
    inline int read(){
        char ch=getchar();int x=0,f=1;
        for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    int main(){
        freopen("sort.in","r",stdin);
        freopen("sort.out","w",stdout);
        n=read();pre=read();
        for(int i=2;i<=n;i++){
            a[i]=read();
            if(a[i]<pre){
                tot++;
                if(tot>1){
                    printf("NO
    ");
                    return 0;
                }
            }
            else pre=a[i];
        }
        printf("YES
    ");
        fclose(stdin);fclose(stdout);
        return 0;
    }
    90

    正解

    在序列不单调时有两种情况。

     

    红色的表示在这个位置发现和前面的序列不能连起来了。那么我们枚举是删去红色的还是删去蓝色的。

    我没有考虑到情况一导致GG,因为我每次删去的红的,而情况一删去蓝的就可以。哦,你不用管移去的数

    插到哪里,反正一定移动后单调了。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define maxn 1000009
    using namespace std;
    int n,js,a[maxn];
    bool no;
    
    inline int read(){
        char ch=getchar();int x=0,f=1;
        for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    bool check(int pos){
        for(int i=1;i<=n;i++){
            if(i==pos)continue;
            if(i-1==pos){
                if(a[i]<a[i-2])return false;
            }else if(a[i]<a[i-1])return false;
        }
        return true;
    }
    
    int main(){
        n=read();
        for(int i=1;i<=n;i++)a[i]=read();
        for(int i=2;i<=n;i++){
            if(a[i]<a[i-1]){
                if(check(i)||check(i-1)){
                }else {
                    no=true;break;
                }
            }
        }
        if(no)puts("NO
    ");
        else puts("YES
    ");
        return 0;
    }
    AC

    题解:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    int a1,b1,a2,b2,a3,b3,a4,b4;
    
    int main(){
        freopen("mod.in","r",stdin);
        freopen("mod.out","w",stdout);
        scanf("%d%d%d%d%d%d%d%d",&a1,&b1,&a2,&b2,&a3,&b3,&a4,&b4);
        for(register int i=0;i<=800000009;i++){
            if((i-b1)%a1!=0)continue;
            if((i-b2)%a2!=0)continue;
            if((i-b3)%a3!=0)continue;
            if((i-b4)%a4!=0)continue;
            printf("%d
    ",i);
            fclose(stdin);fclose(stdout);
            return 0;
        }
        return 0;
    }
    70暴力

    对于30%的数据,枚举x。其实我70暴力就是枚举的x.

    对于60%的数据,中国剩余定理.

    对于100%的数据,用扩展欧几里德将式子合并.

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 5
    #define ll long long 
    using namespace std;
    ll n,m[N],a[N],m1,e;
    ll read()
    {
        ll x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(b==0)
        {
            x=1,y=0;
            return a;
        }
        ll r=exgcd(b,a%b,x,y),tmp;
        tmp=x,x=y,y=tmp-a/b*y;
        return r;
    }
    ll crt()
    {
        ll a1=a[1],a2,m2,d,c;m1=m[1];
        for(ll i=2;i<=n;++i)
        {
            a2=a[i],m2=m[i];
            c=a2-a1;ll x=0,y=0;
            d=exgcd(m1,m2,x,y);
            if(c%d) return  -1;
            x=x*c/d;
            int mod=m2/d;
            x=(mod+x%mod)%mod;
            a1+=m1*x;m1*=mod;
        }
        return a1;
    }
    int main()
    {
    //    freopen("mod.in","r",stdin);
    //    freopen("mod.out","w",stdout);
        n=4;
        for(int i=1;i<=n;i++) 
         m[i]=read(),a[i]=read();
        printf("%lld
    ",crt());
        return 0;
    }
    AC

    题解:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 10009
    using namespace std;
    
    int sumedge,len,tot,head[maxn],sum[maxn][29];
    char s[maxn];
    
    struct Edge{
        int x,y,nxt;
        Edge(int x=0,int y=0,int nxt=0):
            x(x),y(y),nxt(nxt){}
    }edge[maxn];
    
    void add(int x,int y){
        edge[++sumedge]=Edge(x,y,head[x]);
        head[x]=sumedge;
    }
    
    bool check(int l,int r){
        while(l<r){
            if(s[l++]!=s[r--])return false;
        }
        return true;
    }
    
    bool ok(int l,int r){
        for(int i=1;i<=26;i++){
            for(int j=i+1;j<=26;j++){
                int k=sum[r][i]-sum[l-1][i];
                int p=sum[r][j]-sum[l-1][j];
                if(k&&p&&k==p)return true;
            }
        }
        return false;
    }
    
    int main(){
        freopen("str.in","r",stdin);
        freopen("str.out","w",stdout);
        scanf("%s",s+1);len=strlen(s+1);
        for(int i=1;i<=len;i++){
            for(int j=1;j<=26;j++)sum[i][j]=sum[i-1][j];
            sum[i][s[i]-'a'+1]++;
        }
        for(register int i=1;i<=len;i++)
            for(int j=i+1;j<=len;j++)
                if(check(i,j))add(i,j);
        for(int x=1;x<=len;x++){
            for(int i=head[x];i;i=edge[i].nxt){
                int v=edge[i].y;
                if(ok(x,v))++tot;
            }
        }
        printf("%d
    ",tot);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    /*abcbaabcba*/
    30暴力
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    using namespace std;
    
    typedef unsigned long long ULL;
    typedef long long LL;
    
    char s[10005];
    ULL h[10005],rh[10005],pw[10005];
    int L;
    
    ULL hs(int l,int r){
        return h[r]-h[l-1]*pw[r-l+1];
    }
    ULL rhs(int l,int r){
        return rh[l] - rh[r+1]*pw[r-l+1];
    }
    struct N{
        int a[26];
        bool ok(){
            int b[26];
            for(int i=0;i<26;i++) b[i]=a[i];
            sort(b,b+26);
            for(int i=0;i<25;i++){
                if(b[i]>0&& b[i] == b[i+1]) return true;
            }
            return false;
        }
        void clear(){
            memset(a,0,sizeof a);
        }
    };
    LL ans=0;
    map<ULL,LL> num;
    map<ULL,N> A;
    void solve_odd(){
        for(int i=1;i<=L;i++){
            int l = 1,r = min(i,L-i+1)+1;
            while(r-l>1){
                int mid = (l+r)/2;
                if(hs(i-mid+1,i+mid-1)== rhs(i-mid+1,i+mid-1)) l=mid;
                else r=mid;
            }
            int p=l;
            int tmp = p;
            while(tmp>=1&&num.find(hs(i-tmp+1,i+tmp-1))==num.end()) tmp--;
            LL sum = 0;
            N st;
            st.clear();
            if(tmp>=1){
                sum=num[hs(i-tmp+1,i+tmp-1)];
                st = A[hs(i-tmp+1,i+tmp-1)];
            }
            while(tmp<p){
                st.a[s[i+tmp]-'a']+= (tmp == 0?1:2);
                if(st.ok()) sum++;
                num[hs(i-tmp,i+tmp)] = sum;
                A[hs(i-tmp,i+tmp)] = st;
                tmp++;
            }
            ans+=sum;
            // printf("# %d %lld
    ",i,sum);
        }
    }
    void solve_even(){
        A.clear();
        num.clear();
        for(int i=1;i<L;i++){
            // printf("### %d
    ",i);
            int l = 1,r = min(i,L-i)+1;
            while(r-l>1){
                int mid = (l+r)/2;
                if(hs(i-mid+1,i+mid)== rhs(i-mid+1,i+mid)) l=mid;
                else r=mid;
            }
            int p=l;
            int tmp = p;
            while(tmp>=1&&num.find(hs(i-tmp+1,i+tmp))==num.end()) tmp--;
            LL sum = 0;
            N st;
            st.clear();
            // printf("## %d
    ",p);
            if(tmp>=1){
                sum=num[hs(i-tmp+1,i+tmp)];
                st = A[hs(i-tmp+1,i+tmp)];
            }
            while(tmp<p){
                // printf("# %d %lld
    ",tmp,sum);
                st.a[s[i+tmp+1]-'a']+= 2;
                if(st.ok()) sum++;
                num[hs(i-tmp,i+tmp+1)] = sum;
                A[hs(i-tmp,i+tmp+1)] = st;
                tmp++;
            }
            ans+=sum;
            // printf("# %d %lld
    ",i,sum);
        }
    }
    
    int main(){
        freopen("str.in","r",stdin);
        freopen("str.out","w",stdout);
        scanf("%s",s+1);
        L=strlen(s+1);
        s[0]='#';
        pw[0]=1;
        for(int i=1;i<=L;i++) pw[i] = pw[i-1]*13131 ;
        for(int i=1;i<=L;i++) h[i] = h[i-1]*13131 + s[i];
        for(int i=L;i>=1;i--) rh[i] = rh[i+1]*13131 + s[i];
    
        // printf("%llu %llu",hs(1,3),rhs(1,3));
        
        solve_odd();
        solve_even();
        printf("%lld
    ",ans);
        fclose(stdout);
        return 0;
    }
    
    标称(字符串+二分)
    AC
  • 相关阅读:
    计算器程序
    输入三个整数,输出最大数和最小数
    输入三个数a,b,c,要示按由小到大的顺序输出
    最短路
    luogu P3953 逛公园
    二分图匹配
    luogu P3231 消毒
    [bzoj2120] [洛谷P1903] 数颜色
    [bzoj2038] [洛谷P1494] [2009国家集训队] 小Z的袜子(hose)
    [洛谷P4012] [网络流24题] 深海机器人问题
  • 原文地址:https://www.cnblogs.com/zzyh/p/7631684.html
Copyright © 2011-2022 走看看