Topcoder Open 3A (TCO 3A)

开场开250,然后直接交了一发,247分还可以

然后开500,发现是一个很复杂的计算,经过30+分钟终于码掉了

最后开1000,发现不会做 && 大家过了一片...

challenge阶段,觉得250输入2,11能cha一片结果没cha到人

相反,看到一个人4 11输出Bob直接就cha上去了

当然结果.............-25

而且cha了两个,也就是说-50

然后

500fst了真开心

===================================

250

A和B轮流写一个数,然后一共写出一个length位数

A第一位不可以写0

如果这个数是divisor的倍数,那么B赢,不然A赢

问A和B谁能赢?

1 <= length <= 1000

1 <= divisor <= 1000

500

给你一个长度为n的序列a

问有多少个子串,使得其中的积小于limit?

由于这是tc,n又范围要到100000,所以给了你一个数据生成器

最多手动构造500个数,后面的由生成器构造

数据范围:

n<=105

|ai|<=109

0 < limit <=109

1000

给你一个图,每个点度都为3

问你一个01染色方案,使得不存在一个环是同色的

4<=n<=1000,n为偶数

=================================

250

divisor==1 显然Bob赢

否则 length为奇数,Alice赢,理由:

最后一步归Alice

如果放1是divisor的倍数就放2,否则放1就行

否则 divisor>=12 Alice赢,理由:

倒数第二步归Alice

12*4=48,12*5=60

在6个中就有一个选项,让Bob没法放

13是13*4=52

14,15之后就更快了,越来越多的选项让Bob没法放

(不是很会表述QAQ)

否则 divisor <=10 Bob赢

理由:

前面的部分(要乘过10)%divisor = x,最后一个直接补一个divisor-x就好

例如:

4_ % 7

40%7 = 5, 7-5=2

补2即可

=======================

divisor = 11的情况很有趣,也是Bob赢

A放什么,B就放什么,所以这两个数就一定是11的倍数

所以B赢

=======================

虽然这题可以dp,不过如果length和divisor大一点还是可以这么做的

500

情况一大堆

首先先考虑0

____ 0 ____ 0 ___ 0 ____

带0的肯定都符合条件,直接统计?

大概需要一些小技巧不重复的把带0的统计好

比如对于第一个0,统计所有带第一个零的有多少个,直接乘法就可以处理

然后第二个0,我们统计所有带第二个,不带第一个零(也不带它左边的任何数)有多少个,直接乘法

这样下去,我们就把这个问题分成了一些小段

================================

然后我们考虑

由于230>109,我们知道除了1和-1以外,一共乘最多30次,这样不会T

那么我们要特殊处理下1和-1的情况,所以又要写一大堆代码.......

大概类似一个链表一样的..然后暴力....细节挺多的也不知道怎么表达....

不多吐槽...........

然后还要处理负数..所有的负数都是满足条件的,我们要写个dp.......

相比于1000,我为啥不把1000想出来A掉...........

1000

直接dfs,有一颗dfs树

我们把树上的边染成1,树外的染成0就行

我们只要证明,不会有树外的环就行,也就是所有的环都包含一条树边

一个环,肯定不能只有入边,没有出边,所以这个环上的点剩余度数应该是2,所以只可能所有的叶子和根是这样的

那么一个叶子如果连到另外一个叶子,那么这根本不是一个dfs树,因为这个叶子会继续dfs下去的,只可能是返祖边

所以不存在这么一个环........

代码:

250

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
struct LeftToRightGame
{
    string whoWins(int length, int divisor)
    {
        if (divisor==1)
        {
            return "Bob";
        }
        if ((divisor==11)&&(length%2==0)) 
        {
            return "Bob";
        }
        else if ((divisor<=10)&&(length%2==0))
        {
            return "Bob";
        }
        else
        {
            return "Alice";
        }
    }
};
#ifdef absi2011
int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    
    return 0;
}
#endif

500

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int a[100005];
int b[100005];
int next_valid[100005];
int sgn[100005];
int pos[100005],neg[100005];
long long dp[100005][2];
long long solve2(int n,int limit)
{
    b[n]=0;
    int i;
    next_valid[n]=n;
    for (i=n-1;i>=0;i--)
    {
        if ((b[i]==1)||(b[i]==-1))
        {
            next_valid[i]=next_valid[i+1];
        }
        else
        {
            next_valid[i]=i;
        }
    }
    pos[n]=0;
    neg[n]=0;
    sgn[n]=1;
    for (i=n-1;i>=0;i--)
    {
        pos[i]=1;
        neg[i]=0;
        sgn[i]=1;
        if (b[i+1]==1)
        {
            pos[i]=pos[i+1]+1;
            neg[i]=neg[i+1];
            sgn[i]=sgn[i+1];
        }
        else if (b[i+1]==-1)
        {
            pos[i]=neg[i+1]+1;
            neg[i]=pos[i+1];
            sgn[i]=-sgn[i+1];
        }
        else
        {
            continue;
        }
    }
    long long ans=0;
    for (i=0;i<n;i++)
    {
        long long p=b[i];
        int now=i;
        for (;;)
        {
            if ((p>limit)||(p<-limit)) break;
            if (p>0)
            {
                ans+=pos[now];
            }
            else
            {
                ans+=neg[now];
            }
            p*=sgn[now];
            now=next_valid[now+1];
            if (now==n) break;
            p*=b[now];
        }
    }
    for (i=0;i<=n;i++)
    {
        dp[i][0]=0;
        dp[i][1]=0;
    }
    for (i=0;i<n;i++)
    {
        if (b[i]<0)
        {
            dp[i+1][0]=dp[i][1];
            dp[i+1][1]=dp[i][0]+1;
        }
        else
        {
            dp[i+1][0]=dp[i][0]+1;
            dp[i+1][1]=dp[i][1];
        }
        ans+=dp[i+1][1];
    }
    return ans;
}
long long solve(int n,int limit)
{
    int i;
    long long ans=0;
    int last_zero=-1;
    for (i=0;i<n;i++)
    {
        if (a[i]==0)
        {
            ans=ans+(long long)(i-last_zero)*(n-i);
            last_zero=i;
        }
    }
    last_zero=0;
    for (i=0;i<n;i++)
    {
        if (a[i]==0)
        {
            //(last_zero,i)
            memcpy(b,a+last_zero,sizeof(int)*(i-last_zero));
            ans=ans+(long long)solve2(i-last_zero,limit);
            last_zero=i+1;
        }
    }
    memcpy(b,a+last_zero,sizeof(int)*(i-last_zero));
    ans=ans+(long long)solve2(i-last_zero,limit);
    return ans;
}
struct ProductThreshold
{
    long long subarrayCount(int n, int limit, vector <int> Aprefix, int spread, int offset)
    {
        int p=Aprefix.size();
        int i;
        for (i=0;i<p;i++)
        {
            a[i]=Aprefix[i];
        }
        int seed=abs(a[p-1]);
        for (i=p;i<n;i++)
        {
            seed = (seed * 1103515245ull + 12345) % (1ll<<31);
            a[i] = (seed % spread) + offset;
        }
        return solve(n,limit);
    }
};
#ifdef absi2011
int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    ProductThreshold aa;
    int n=5;
    int l=8;
    static int aaa[]={3,-1,3,-1,3};
    vector<int> ap;
    for (int i=0;i<sizeof(aaa)/sizeof(int);i++)
    {
        ap.push_back(aaa[i]);
    }
    int s=1;
    int o=1;
    cout<<aa.subarrayCount(n,l,ap,s,o)<<endl;
    return 0;
}
#endif

1000

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
struct edge
{
    int y;
    int id;
    edge * next;
};
edge * li[1005];
edge * new_edge()
{
    static edge a[100005];
    static int top=0;
    return &a[top++];
}
void inserts(int x,int y,int z)
{
    edge * t=new_edge();
    t->y=y;
    t->id=z;
    t->next=li[x];
    li[x]=t;
}
void insert_edge(int x,int y,int z)
{
    inserts(x,y,z);
    inserts(y,x,z);
}
int col[10005];
bool vis[10005];
void dfs(int x)
{
    vis[x]=true;
    edge * t;
    for (t=li[x];t!=0;t=t->next)
    {
        if (!vis[t->y])
        {
            col[t->id]=1;
            dfs(t->y);
        }
    }
}
struct ColoringEdgesDiv1
{
    vector <int> findColoring(int n, vector <int> x, vector <int> y)
    {
        srand(time(0));
        int i;
        for (i=0;i<n+n/2;i++)
        {
            insert_edge(x[i],y[i],i);
        }
        for (i=0;i<n;i++)
        {
            if (!vis[i])
            {
                dfs(i);
            }
        }
        vector<int> ans;
        for (i=0;i<n+n/2;i++)
        {
            ans.push_back(col[i]);
        }
        return ans;
    }
};
#ifdef absi2011
int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    static int a[]={2, 0, 3, 1, 1, 0, 0, 2, 4};
    vector<int> ap;
    for (int i=0;i<sizeof(a)/sizeof(int);i++)
    {
        ap.push_back(a[i]);
    }
    static int b[]={3, 3, 1, 5, 4, 2, 4, 5, 5};
    vector<int> bp;
    for (int i=0;i<sizeof(b)/sizeof(int);i++)
    {
        bp.push_back(b[i]);
    }
    ColoringEdgesDiv1 aa;
    aa.findColoring(ap.size()/3*2,ap,bp);
    return 0;
}
#endif

  

猜你喜欢

转载自www.cnblogs.com/absi2011/p/9281956.html
3A