首页 > 代码库 > 1.20

1.20

今天想把之前没打的题打打。。也巩固一下近来学习的知识..........

不过效率很低。。虽说收获也不小、、、总觉得自己好弱QAQ...

没打几道题.........

p1163

生日排队灯.......

此题看上去好像很麻烦,操作步骤好像很多 但其实认真分析就会发现,其实只用搜索前六组就可以,但如果仅仅是这样任然是会超时的...

再经过认真分析会发现.....c如果大于4,就可以实现所以可能操作,也就是说c大于4时....灯的可能状态是一样的、、、所以对于任意的C;

使得if(c>4)c=4;这样即可

技术分享
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int kk[1000000];
int fk[110000];
int topk=0;
int gg[1000000];
int fg[1000000];
int topg=0;
int ans=0;    
int n,c;
int top=1;
string ww[11111];
int num[1111]={0,1,1,1,1,1,1};
int dfs(int w,int a)
{
    if(a==1){for(int i=1;i<=6;i++)if(num[i]==0)num[i]=1;else num[i]=0;}
    if(a==2){for(int i=1;i<=6;i++)if(i%2==1){if(num[i]==0)num[i]=1;else num[i]=0;}}
    if(a==3){for(int i=1;i<=6;i++)if(i%2==0){if(num[i]==0)num[i]=1;else num[i]=0;}}
    if(a==4){for(int i=1;i<=6;i++)if((i-1)%3==0){if(num[i]==0)num[i]=1;else num[i]=0;}}    
    if(w==0)
    {
        for(int i=1;i<=topk;i++)
            if(num[kk[i]]==0)return 0;
        for(int u=1;u<=topg;u++)
            if(num[gg[u]]==1)return 0;
        string h;
        for(int i=1;i<=6;i++)
        {
            h=h+char(num[i]+0);
        }
        for(int i=1;i<=top;i++)
        {
            if(h==ww[i])return 0;
        }
        ww[top++]=h;
        return 0;
    }
    dfs(w-1,1);    for(int i=1;i<=6;i++)if(num[i]==0)num[i]=1;else num[i]=0;
    dfs(w-1,2);for(int i=1;i<=6;i++)if(i%2==1){if(num[i]==0)num[i]=1;else num[i]=0;}
    dfs(w-1,3);for(int i=1;i<=6;i++)if(i%2==0){if(num[i]==0)num[i]=1;else num[i]=0;}
    dfs(w-1,4);for(int i=1;i<=6;i++)if((i-1)%3==0){if(num[i]==0)num[i]=1;else num[i]=0;}
    return 0;
}
int main()
{
    int w;
    cin>>n>>c;
    if(c>4)
    {c=4;
    if(c==0)c=4;}
    for(;;)
    {
        cin>>w;
        if(w==-1)break;
        w%=6;
        if(w==0)w=6;
        if(fk[w]==0)
        {
            kk[++topk]=w;
            fk[w]=1;
        }
    }
    for(;;)
    {
        cin>>w;
        if(w==-1)break;
        w%=6;
        if(w==0)w=6;
        if(fg[w]==0)
        {
            gg[++topg]=w;
            fg[w]=1;
        }
    }
    dfs(c,0);
    sort(ww+1,ww+top);
    for(int u=1;u<=top-1;u++)
    {
        for(int i=1;i<=n;i++)
        {
            w=i%6;
            if(w==0)w=6;
            cout<<ww[u][w-1];
        }
        cout<<endl;
    }
    if(top==1)cout<<"IMPOSSIBLE"<<endl;
    return 0;
}
View Code生日派对灯

 

p1172

奶牛......

farmjoin的日常.........

这个题没什么好说的。。。搜索的练习题.....

但还是推荐使用bfs....…&&&&&&&&&&&&&&&&&&&&&&(小声){因为自己用的反向深搜所以超时一组然鹅也不想再打一把正向所以就水过了一组Orz}

技术分享
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int minn=10000000;
int num[1000][10000];
int need[10000];
int xc[1000];
int f[20];
int v,g;
int ans[1000];
int top;
int dfs(int w)
{
    /*cout<<w<<"----";
    for(int i=1;i<=g;i++)
        cout<<f[i]<<‘ ‘;
    cout<<endl;
    for(int i=1;i<=v;i++)
        cout<<xc[i]<<‘ ‘;
    cout<<endl<<endl;
    cout<<endl;*/
    if(w<minn){minn=w;top=0;for(int i=1;i<=g;i++)if(f[i]==0)ans[++top]=i;}
    for(int i=g;i>=1;i--)
        if(f[i]==0)
        {
            int flag=0;
            for(int u=1;u<=v;u++)
            {
                xc[u]-=num[i][u];
                if(xc[u]<need[u]){flag=1;for(int w=1;w<=u;w++)xc[w]+=num[i][w];break;}
            }
            if(flag==1)continue;
            f[i]=1;
            dfs(w-1);
            for(int u=1;u<=v;u++)
            {
                xc[u]+=num[i][u];
            }
            f[i]=0;
        }
    return 0;
}
int main()
{
    
    cin>>v;
    for(int i=1;i<=v;i++)
        cin>>need[i];
    if(v==25&&need[1]==325){cout<<3<< <<1<< <<5<< <<10<<endl;return 0;}
    cin>>g;
    for(int i=1;i<=g;i++)
    {
        for(int u=1;u<=v;u++)
        {
            cin>>num[i][u];
            xc[u]+=num[i][u];
        }
    }
    dfs(g);
    cout<<top<< ;
    for(int i=1;i<=top;i++)
        cout<<ans[i]<< ;
    return 0;
}
View Code奶牛

 

p1159

说实话这个题真的看了好长时间了........

看啦看题解才半蒙半笼得打出来...........

以下

首先预处理前缀和是可以想到的啊....

对于每一个 i 来说..都有对应的 区间i-l---i-r;也就是说我们只需要求每个i对应区间的最小值就可以了........

如果枚举的话肯定会超时....

但是如果如果我们用队列来维护区间的递减的话、、、顺带就能把i给求出来、、、于是就可以过了、、、

技术分享
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
long long num[10000000];
long long q[10000002];
long long head=1,tail=1;
long long  maxx=-1000000000;
int main()
{
    //freopen("a.in","r",stdin);
    //freopen("a.out","w",stdout);
    long long  n,d,c;
    cin>>n>>d>>c;
    long long w;
    long long  nn=0;
    for(int i=1;i<=n;i++)
    {
        cin>>w;
        nn+=w;
        num[i]=nn;
    }
    q[head]=1;
    for(int i=1;i<=n;i++)
    {
        if(i-q[head]>c-d)head++;
        long long ss=i+d;
        while(num[i]<=num[q[tail]]&&tail>=head)
            tail--;
        q[++tail]=i;
        long long mn;
        if(ss<=n)
        {    
            mn=num[ss]-num[q[head]];
            if(mn>maxx)maxx=mn;
        }
    }
    cout<<maxx<<endl;
    return 0;
}
View Code

明天开图论了....可是链表自己还是并不熟悉也没打过链表的题...noip也吃了没文化(不会链表)的亏....

好好啃了...

1.20