NOIP2017 time complexity of the problem solution

Foreword

Two years. Pay tribute to the hard work of that period of time.

analysis

Topic link: Time complexity of the
topic seems simple but full of traps , because I was not considered a problem only got back 40 points. Heartache.
Title to see myself, I first analyze ideas

! If x = n & y = n - > answer a plus.
If (! X = n & y = n) or (x = C & y = C & x> y) -> error loop, loop below him are invalid
other cases -> the same answer, the following loop effective
repetition after the variable appears his answer is ERR
recording layers wrong cycle, such as this one out then delete the record. In the meantime try any of the inputs are invalid.
If there is a constant level of cycling we have from the beginning that one of the earliest records, there are few records of several, layers of F minus the time with him and then with ans maximum value.

We analyze ixy every input, it is above ideas.
Paste code first:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define N flag_one[1] //把后面的替换成前面的,省事。
using namespace std;
int n;
int T;
int F;//代表循环的深度
int ans;//所得的答案
int true_ans;//真正的答案
int code_status;//0-->yes 1-->no 2-->ERR//其实我只用到了ERR
char every_var;//输入的变量名
char sstart[50],eend[50];//x y
char tmp_str[20];
bool vis[30];//记录变量有没有出现过
char stack[200];//当前状态有多少个变量
int flag[2];//flag[0]==1-->wrong for !! 0--->true for .   flag[1]==x --->F==x wrong
int flag_one[2];//记录常数级别循环 [1] --> 第几层 [2] --> 有几个
int find_true_ans()
{
    int ans=0;
    int len = strlen(tmp_str);
    ans += tmp_str[len-2]-'0';//O()
    //if(tmp_str[len-3] != '^' && tmp_str[len-3] != '(')ans += (tmp_str[len-3] - '0')*10;// ( 应该是0回头改
    if(tmp_str[len-3] == '(')return 0;
    if(tmp_str[len-3] != '^' && tmp_str[len-3] != '(')ans += (tmp_str[len-3] - '0')*10;// ( 应该是0回头改
    return ans;
}
void init()//初始化
{
    scanf("%d",&n);
    memset(stack,0,sizeof(stack));
    memset(vis,0,sizeof(vis));
    code_status=0;
    cin>>tmp_str;
    true_ans = find_true_ans();
    ans = 0;
    flag[0] = 0;
    flag[1] = 0;
    flag_one[0] = 0;
    flag_one[1] = 0;
    F=0;
}
bool duex(char check)
{
    int ans = check - 'a' + 1;
    if(vis[ans])return true;
    return false;
}
void del()//删除
{
    int ans = stack[F] - 'a' + 1;
    vis[ans] = 0;
    stack[F] = 0;
    F--;
    if(flag[1]>F)flag[1] = 0,flag[0] = 0;
    if(flag_one[0])N--;
    if(flag_one[0]>F)flag_one[1] = 0,flag_one[0] = 0;
    
}
bool cnm()//比较常数循环是否正确。
{
    int a1,b1;
    int len_a = strlen(sstart);
    int len_b = strlen(eend);
    if(len_a == 1)a1 = sstart[0] - '0';
    else a1 = (sstart[0] - '0') * 10 + (sstart[1] - '0');
    if(len_b == 1)b1 = eend[0] - '0';
    else b1 = (eend[0] - '0') * 10 + (eend[1] - '0');
    return a1>b1;
}
int main()
{
    int i;
    scanf("%d", &T);
    while(T--)
    {
        init();
        for(i=1;i<=n;i++)
        {
            char tmp_status;
            cin>>tmp_status;
            if(tmp_status == 'E'){del();continue;}//wa
            if(tmp_status == 'F')
            {
                F++;
                cin>>every_var>>sstart>>eend;
                //变量已经重复和出现重复的直接标记跳过
                if(duex(every_var)){code_status=2;continue;}
                if(code_status == 2 || flag[0])continue;
                //比较一下start和end的大小,大到小就错了
                if(sstart[0] != 'n' &&  eend[0] == 'n')
                {
                    ans = max(ans,F-N);//wawawa
                    int ascii = every_var - 'a' + 1;//97-122; 
                    stack[F] = every_var;
                    vis[ascii] = 1;
                }
                else if((sstart[0] == 'n' && eend[0] != 'n')|| cnm())//have wrong can not enter
                {
                    flag[0] = 1;
                    flag[1] = F;
                    ans = max(ans,F-N-1);
                }
                else
                {
                    if(!flag_one[0])flag_one[0] = F;
                    N++;
                    int ascii = every_var - 'a' + 1;//97-122;
                    stack[F] = every_var;
                    vis[ascii] = 1;
                    ans = max(ans,F-N-1);
                }
            }
        }
        if(F!=0)code_status = 2;
        if(code_status == 2)printf("ERR\n");
        else if(ans == true_ans)printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

to sum up

I think the difficulty is the need to record which one cycle and the beginning of errors constant cycle. Other better. I was too dishes. This problem is also made more than happy to make the robot move heavy objects.

Published 36 original articles · won praise 29 · views 3946

Guess you like

Origin blog.csdn.net/YUK_103/article/details/103193892