10.5 simulated match

well,the code is the best language

#include<cstdio>
using namespace std;
#define ct   register int
#define fr(a,b,c)   for(ct a=b;a<=c;a++)
#define init(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); 
int read(){ct f=1,x=0;char c=getchar();
   for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
   for(;'0'<=c&&c<='9';c=getchar())x=(x<<1)+(x<<3)+(c^48);return x*f;}
char st[100005];int n,p;
//st:string
//n:the length of string 
//p:the section of choosable lectures
void Build(int x){
    fr(i,x,n)//make a loop from x to n
    fr(j,0,p-1)//make a loop : 0<j<p
            if((i<=1||j!=st[i-1]-'a')&&(i<=2||j!=st[i-2]-'a'))//this judge is same with the judge below
            {st[i]=j+'a';break;}//if need change just change it to avoid the parlindrome_case
    printf("%s",st+1);//after operating ,just out the solution
}
int main(){init("string");
    n=read();p=read();//read the length of string and the section of choosable lectures
    scanf("%s",st+1);//read the string
    for(ct i=n;i;--i)//make a loop from n to 1,this is a greedy part,
    //if we find choosable case,it's easy to prove it's the best solution(smallest Lexicographic order)
    fr(j,st[i]-'a'+1,p-1)//here,we set a as 0 and we can make a loop against choosable lectures
        if((i<=1||j!=st[i-1]-'a')&&(i<=2||j!=st[i-2]-'a'))//here we make a judge,in order to cut some unnecessary operation
        //if i==1,just means that it can't be same with lectures before(OF COURSE),just make operation
        //or if the location is bigger than 1,just means that there is at least one lecture before it,in this case we
        //need to check it with a palindrome_case .for example:aa,it's a palindrome ,so we can't operate it
        //another case is that the location is bigger than 2,just means that there is at least two lectures before it,
        //in this case ,we need to check it with a palindrome_case. for example:aba,it's a palindrome ,so we can't operate it
        {st[i]=j+'a';Build(i+1);return 0;}//just change it and then try to work on it,and judge the lectures behind
        //so that we can work out a pretty_string
    puts("NO");return 0;//if we can't work out the pretty_string
    //this solution has two case
    //1:the given_lecture_section can't satisfy a pretty_string(most possible)
    //2:the given string is not pretty_string (may impossible)
}

 

 

 

 


 

 

 

 

 

 

well,the code is the best language

#include<cstring>
#include<cstdio>
#define MN 100000
using namespace std;
#define ct   register int
#define fr(a,b,c)   for(ct a=b;a<=c;a++)
#define init(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); 
int read(){ct f=1,x=0;char c=getchar();
   for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
   for(;'0'<=c&&c<='9';c=getchar())x=(x<<1)+(x<<3)+(c^48);return x*f;}
int n,lt=0,f[100005];//lt:longest_length
int main(){init("sorting");n=read();//read the total_number of the array
    int x,ans=0;
    fr(i,1,n)//make a loop from 1 to n ,to read the array
    x=read(),ans=ans>f[x-1]+1?ans:f[x-1]+1,f[x]=f[x-1]+1;
    //read the array ,if the longest_length can make better,just renew it.mark the length
    
    //here ,we use a greedy algorithm,we need to find a longest_strict_increasing_part,
    //this part we don't need to change it ,for example:2345 among 7234516 is the longest
    //we only need to change other number's location ,and it's easy to prove this is the best solution
    
    //why :f[x]=f[x-1]+1? if a section is incremental,the sum before it must have been marked
    //pay attention to the problem ,the array includes 1~n,
    //so if a section is incremental,it must be look like 2345 or 5678 so that we don't need to change it to make it ordered
    //for example:1 5 6 2 3 4
    //f[5]=1 because it can't form a incremental section,f[6]=2 because it can form a incremental section:5,6
    //Similarly f[2]:1 f[4]:3;in this way,we can easily work out the length of the increasing_section's length including x by now
    printf("%d",n-ans);return 0;//then the operation_time is just n-ans
}

 

 

 

 


 

 

 

 

well ,the code is the best language

//!!!pay attention here!!!
//!!!in this program,we use A,B,C,D to replace the wanted_four_sites!!!
//!!!in this way,we can think of the program more intuitively!!!
#include<cstring>
#include<cstdio>
#define MN 2000
using namespace std;
#define ct   register int
#define fr(a,b,c)   for(ct a=b;a<=c;a++)
#define init(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); 
#define b()    fr(i,1,n)fr(j,1,n)if(i!=j&&d[i][j]<1e9)
int read(){ct f=1,x=0;char c=getchar();
   for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
   for(;'0'<=c&&c<='9';c=getchar())x=(x<<1)+(x<<3)+(c^48);return x*f;}
int head[MN+5],cnt=0,n,m,d[MN+5][MN+5],q[MN+5],top,ans,a[4];
int mx[3][MN+5],from[3][MN+5],Mx[3][MN+5],From[3][MN+5];
//from/From(from_a_to_b and from_b_to_a):the_point_which_the_road_against of three longest road
//mx/Mx(from_a_to_b and from_b_to_a):the three longest road
//why we need to save respectively,because it's an oriented graph
struct edge{int to,next;}e[MN*2+5];
inline void ins(int f,int t){e[++cnt].to=t,e[cnt].next=head[f],head[f]=cnt;}
//ins:insert,use this to add an edge from f to t
//head[] used to mark the edge_from_f's location in e[]
void add(int fromm[][MN+5],int mxx[][MN+5],int x,int y,int len){
    //fromm:the_point_which_the_road_against of three longest road
    //mxx:the three longest road
    //x:from y:to len:the given_distance
    if(len>mxx[0][x])//if the max_length can make better
        fromm[2][x]=fromm[1][x],mxx[2][x]=mxx[1][x],//save the before_one to replace the next_one(*)
        fromm[1][x]=fromm[0][x],mxx[1][x]=mxx[0][x],//the same operation 
        fromm[0][x]=y,mxx[0][x]=len;//renew the longest one
//here we use fromm[0]~[2][x] respectively save the longest one ,second_longest one,third_longest one.
//in this way ,we can improve the efficiency in the next few operations
    else if(len>mxx[1][x])//or ,just means that the given_distance is smaller than longest one
    //just try to renew the second_longest one,if can make better,just make it better
        fromm[2][x]=fromm[1][x],mxx[2][x]=mxx[1][x],//the same operation 
        fromm[1][x]=y,mxx[1][x]=len;//renew the second_longest one
    else if(len>mxx[2][x])//or ,just means that the given_distance is smaller than the second_longest one
    //just try to renew the third_longest one,if can make better,just make it better
    fromm[2][x]=y,mxx[2][x]=len;//just renew it,because we only save three longest distance,and it's the last one,
    //so we don't need any change like before
}
inline void R(int A,int B,int C,int D,int res){if(res>ans) ans=res,a[0]=A,a[1]=B,a[2]=C,a[3]=D;}
int main(){
    init("travel");n=read();m=read();memset(d,63,sizeof(d));
 //read the total_number of sites,and the total number of roads.Then initializate the array:d
    ct st,fn;fr(i,1,m)st=read(),fn=read(),ins(st,fn);//read each road's starting point and the finishing point
    //and then insert this edge
    //-----------------------------------------------------------------------------------------------------
    fr(i,1,n){//make a loop from 1 to n
        d[i][q[top=1]=i]=0;//set queue_top as 1 and make queue[1] as i and then make distance[i][i] as 0
        //-_-..of course,visit oneself need distance?
        fr(j,1,top)//make a loop from 1 to top
            for(ct k=head[q[j]];k;k=e[k].next)//visit every edge started from queue[j]
                if(d[i][q[j]]+1<d[i][e[k].to])//if the distance can make smaller
                d[i][q[++top]=e[k].to]=d[i][q[j]]+1;}//just push it to the queue and renew it's distance
    //!!!why we do this!!!
    //!!!against this problem ,there are two query:longest among smallest!!! 
    //------------------------------------------------------------------------------------------------------
    //b():fr(i,1,n)fr(j,1,n)if(i!=j&&d[i][j]<1e9)
    //that means 1<=i<=n,1<=j<=n;if this road is not against oneself and it has distance(just has possible road between them)
    //here ,we regard i as B,and j as C
    b()add(From,Mx,j,i,d[i][j]),add(from,mx,i,j,d[i][j]);
    //if satisfy,just respectively work out three_longest_distance from C to B and from B to C
    //and then respectively mark the three_lonest_way into the From,Mx and from,mx
    //----------------------------------------------------------------------------------------------------
    //by now, we have work out the choose_possible_section already(against B and C)
    //and then we need to enumerate A and D.this work is easy,but you should know that we can't make them the same
    b()fr(k,0,2)if(From[k][i]!=j&&From[k][i])
    //if satisfy,just means that they are possible and we have work out the possible_section of them already
    //depend on this,just make a loop 0<=k<=2 to enumerate the three_longest_distance from C to B
    //then make a judge:(here we expect From[k][i] as A,j as C)if A has been marked and A is not same with C
    //just means this A satisfies the limiting_condition(can't be same as others)
        fr(l,0,2)//make a loop 0<=l<=2,to enumerate the three_longest_distance form B to C
        if(from[l][j]!=i&&from[l][j]!=From[k][i]&&from[l][j])
        //make a judge:(here we expect from[l][j] as D,i as B)if D is not B,and D is not same as A and D has been marked
                    R(From[k][i],i,j,from[l][j],Mx[k][i]+d[i][j]+mx[l][j]);//just mark the answer
    printf("%d %d %d %d",a[0],a[1],a[2],a[3]);return 0;//out the answer
}

 

posted @ 2017-10-05 13:30  yodel  阅读(195)  评论(1编辑  收藏  举报