CERC2017 Kitchen Knobs

Posted by Sayian on Sun, 29 Dec 2019 19:44:07 +0100

You're cooking on a giant stove in a large fast food restaurant. There are n stoves in a row on this stove, and they are numbered 1-n in sequence. Every furnace is controlled by its control handle. These handles are unusual: each handle has a 1-7 number around it. The firepower of the stove is obtained by reading the number clockwise from the top of its control handle.

You can turn one or more adjacent handles at each step - several times in any direction. However, the handle rotated in the same step can only be rotated in the same direction for the same number of times.

Find the minimum number of steps to set all furnaces to the maximum possible fire.

Thinking problem is also the gold medal of this competition

But do you think you can't get the NOIP? It's not no

This question examines the concept of generalized goods and the application of difference (isn't this all the knowledge points of NOIP)

The first discovery only needs to turn clockwise. (counter clockwise equals clockwise + 7)

In this case, the problem is transformed into: adding and taking membrane (7) to a section to make the section become all zero.

It seems that all zeros are single point, so consider the sequence difference

In this case, it is converted to single point modification of the difference sequence, and it becomes all zeros

Consider pairing 1-6 2-5 3-4

Why are these things right?

The reason is that 1 difference is - 1 + 1, which makes it legal for 6 to become 7

And then I'll find the most all zero groups.

A group that adds up the value of mod for 7 to 0 is called all 0 group

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+100;
typedef int INT;
#define int short
inline void up(int&a,int b){a>b?(a=b):0;}
const int INF=1e4+7;
inline int Get(char *S){
    int l=0,r=1,len=0;
    while(l<7&&r<7&&len<7){
        int t=S[(l+len)%7]-S[(r+len)%7];
        if(t==0){
            len++;
        }
        else{
            if(t<0){
                l+=(len+1);
            }
            else r+=(len+1);
            if(l==r)r++;
            len=0;
        }
    }	
    int now=-1;
    for(int i=1;i<7;++i){
        if(S[i]!=S[i-1])now=1;
    }
    if(now==-1)return now;
    return min(l,r);
}
char S[N];
int v[N];
int n;
int cnt[7];
struct Node{
    int a,b,c,v;
}e[N];
int tot=0;
int F[501][501][501];
int ans=0;
int A,B,C;
int x,y,z;
INT main(){
//	freopen("test.in","r",stdin);
    INT Cas;
    scanf("%d",&Cas);
    while(Cas--){
        scanf("%s",S);
        int sum=Get(S);
        if(sum>=0)v[++n]=sum;
    }
    for(int i=n+1;i;--i)v[i]-=v[i-1];
    for(int i=1;i<=n+1;++i)(v[i]=(v[i]+7)%7);
    n++;
    for(int i=1;i<=n;++i)++cnt[v[i]];
    while(cnt[1]&&cnt[6])cnt[1]--,cnt[6]--,ans++;
    A=cnt[1]?cnt[1]:cnt[6];
    x=cnt[1]?1:6;
    while(cnt[2]&&cnt[5])cnt[2]--,cnt[5]--,ans++;
    B=cnt[2]?cnt[2]:cnt[5];
    y=cnt[2]?2:5;
    while(cnt[3]&&cnt[4])cnt[3]--,cnt[4]--,ans++;
    C=cnt[3]?cnt[3]:cnt[4];
    z=cnt[3]?3:4;
    for(int i=0;i<=7;++i){
        for(int j=0;j<=7;++j){
            for(int k=0;k<=7;++k){
                if(i+j+k&&(i*x+j*y+k*z)%7==0){
                    ++tot;
                    e[tot].a=i;
                    e[tot].b=j;
                    e[tot].c=k;
                    e[tot].v=i+j+k-1;
                }
            }
        }
    }
    for(int i=0;i<=A;++i){
        for(int j=0;j<=B;++j){
            for(int k=0;k<=C;++k){
                if(i+j+k){
                    int sum=INF;
                    for(int t=1;t<=tot;++t){
                        if(i>=e[t].a&&j>=e[t].b&&k>=e[t].c){
                            up(sum,F[i-e[t].a][j-e[t].b][k-e[t].c]+e[t].v);
                        }
                    }
                    F[i][j][k]=sum;					
                }
            }
        }
    }
    cout<<ans+F[A][B][C];
}