EZ 2018 05 06 NOIP2018 Cixi Middle School Training Team Mutual Test (5)

Enjoy the thrill of breaking zero

Lao Ye originally asked the third graders to play, and then my SB went to join in the fun.

TM's T2 was written to explode (go to your sister's optimization), T1 even forgot to score -1, T3 of course not

Glorious Revolution!

T1

Mind map topic, CHJ dalao gave a positive solution but -1 lost to 0 and remembered

And this question can't be read with excellentmetaphysics

The idea is also very novel, first run MST again to determine whether there is no solution

Then look at how many edges are connected to 1 in MST

If it is less than k, then we subtract a value from all edges connected to 1 to make them preferentially selected, and then run MST

If it is greater than k, add it

Note that this value can be divided into two , so keep doing MST

CODE

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5005,M=100005;
const double EPS=1e-5;
struct data
{
    int l,r,s;
    double add;
}a[M];
int n,m,k,cnt,father[N],tot;
long long ans;
inline bool comp(data a,data b)
{
    return a.s+a.add<b.s+b.add;
}
inline int getfather(int k)
{
    return father[k]==k?k:father[k]=getfather(father[k]);
}
inline int MST(double x)
{
    register int i; int res=0,tot=0;
    for (i=1;i<=m;++i)
    if (a[i].l==1||a[i].r==1) a[i].add=x;
    sort(a+1,a+m+1,comp);
    for (i=1;i<=n;++i)
    father[i]=i; ans=0;
    for (i=1;i<=m;++i)
    {
        int fx=getfather(a[i].l),fy=getfather(a[i].r);
        if (fx!=fy)
        {
            if (a[i].l==1||a[i].r==1) ++res;
            ans+=a[i].s; ++tot;
            father[fx]=fy;
        }
    }
    if (tot!=n-1) return -1;
    return res;
}
int main()
{
    freopen("path.in","r",stdin); freopen("path.out","w",stdout);
    register int i;
    scanf("%d%d%d",&n,&m,&k);
    for (i=1;i<=m;++i)
    {
        scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].s);
        if (a[i].l==1||a[i].r==1) ++tot;
    }
    if (tot<k||MST(0)==-1) { puts("-1"); return 0; }
    double l=-100000.0,r=100000.0;
    while (r-l>EPS)
    {
        double mid=(l+r)/2.0; 
        int t=MST(mid);
        if (t==k) { printf("%lld",ans); break; }
        if (t>k) l=mid; else r=mid;
    }
    return 0;
}

T2

Such a small data range is the DP of the routine.

I'm the only one who thinksmemoized searchViolent metaphysics search?

Well it's me ZZ again

First of all, it is found that the range of n is only 15, and it is decisively pressed into a string of 01 to indicate which string to choose or not to choose.

Then preprocess an array g[i][j] to indicate the matching situation with other strings when the character on t[i] is j (represented by binary down-compressed 01 string)

For example, the four strings are

? a?
ab?
aa?
?? b

E.g

  • g[2]['a']=1101 (matches the fourth, third, and first strings respectively)=13

  • g[1]['a']=1111=15

Then we set the DP array f[i][j] to represent the total number of schemes when the matching situation of all strings is j (01 string in binary) when the i-th bit is matched (the i-th bit has not yet been matched)

Then there is f[i][j] that can be transferred out

f[i+1][j&g[i][ch]]+=f[i][j]('a'<=ch<='z')

Because as long as one position does not match, the entire string does not match, so only 1 on both sides can meet the requirements

Finally ans+=f[len+1][j] where the number of 1s of all j is exactly k

C++ does not have character-indexed arrays, so subtract 'a' from all characters

CODE

#include<cstdio>
#include<cstring>
using namespace std;
const int N=20,D=50,mod=1000003;
int g[D+5][30],f[D+5][(1<<N+1)+5],n,k,ans,t;
char s[N][55],ch;
inline int count(int x)
{
    int tot=0;
    while (x) tot+=x&1,x>>=1;
    return tot;
}
int main()
{
    freopen("question.in","r",stdin); freopen("question.out","w",stdout);
    register int i,j; scanf("%d",&t);
    while (t--)
    {
        memset(f,0,sizeof(f));
        memset(g,0,sizeof(g));
        scanf("%d%d",&n,&k);
        for (i=1;i<=n;++i)
        scanf("%s",s[i]+1); int len=strlen(s[1]+1);
        for (i=1;i<=len;++i)
        for (ch='a';ch<='z';++ch)
        for (j=1;j<=n;++j)
        if (s[j][i]=='?'||ch==s[j][i]) g[i][ch-'a']|=1<<j-1;
        f[1][(1<<n)-1]=1; ans=0;
        for (i=1;i<=len;++i)
        for (j=0;j<1<<n;++j)
        if (f[i][j]) for (ch='a';ch<='z';++ch)
        f[i+1][j&g[i][ch-'a']]=(f[i+1][j&g[i][ch-'a']]+f[i][j])%mod;
        for (i=0;i<1<<n;++i)
        if (count(i)==k) ans=(ans+f[len+1][i])%mod;
        printf("%d\n",ans);
    }
    return 0;
}

T3

Is this the legend of the gods?

The idea of ​​violence is there, but it just doesn't come out (only YZC dalao got 2 points)

Scaling is DP+KMP+matrix multiplication (fast power) , still not edible

For students who want to calculate, see BZOJ1009 , Senior Huang's Problem Solution

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325843979&siteId=291194637