A Hard Problem

真就看样例猜呗就,,猜着是2 3 3 4 4 5 5 。。这样子的规律尝试写了写还真。。。过了???
一共就两个样例,不过不加关流第二个就挂掉了QAQ,真是短小精悍的样例
int main()
{
    fast;
    int t;cin>>t;
    while(t--)
    {
        int n;cin>>n;
        if(n==2) cout<<2<<endl;
        else
        {
            n-=1;n/=2;
            cout<<n+2<<endl;
        }
        
    }
    return 0;
}


H. Prince and Princess

依然是看样例猜代码~不过这次 W !A! 的 !很 !快 ! (o゜▽゜)o☆
因为有个特殊情况,如果是1 0 0 的话,是不需要问的!因为那个人就是公主🌶(读题还是要更仔细些)
int a,b,c;
int main()
{
    cin>>a>>b>>c;
    if(a==1&&!b&&!c) cout<<"YES\n0\n";
    else if(a>b+c) cout<<"YES\n"<<(b+c)*2+1<<endl;
    else cout<<"NO\n";
    return 0;
}

C. Digital Path(拓扑排序)

这道题应该这么想 :(大概)

很容易想到某点的路径长度可以由他附近的点推出,
怎么知道路过该点的路径长度和路径条数?题目中要求是路径长度大于等于四,所以大于等于四的路径长度都是等价的
那么就需要开四个数组来记录路过当前结点长为1,2,3,4及以上,的路径条数,
再者,怎么搜的问题,直接从(1,1)开始搜?这样可能存在路径为 4 3 2 1 的情况(你不会天真到四个方向全搜一遍吧讲真(○´・д・)ノ)
那么现在的问题就是:从哪开始搜,记录答案的时候如何保证一条路只记录一次(从哪记),搜索时怎么保证一个路只被搜一次(不要在岔路口走到已经搜过的路上去)

这类问题,就需要在点之间建边,这里采取从低指向高的方法,如:1====>2====>3,
这样记录下每个点的入度出度之后,每条路的起终点就很好找,(入度或出度为零),

建图再次联想到我们每次找出一条路就是从原图中抽出一长条边,再仔细一想这不就是拓扑排序吗???
算法基础还是太薄弱了/
类似于这种每个状态都要取决于上一个状态的图,可以试试拓扑排序

const int mod = 1e9+7;
int n,m,a[1111][1111],dp[1111][1111][5];
int in[1111][1111],out[1111][1111],dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
void topo()
{
    queue<pii>q;
    rpp(i,n) rpp(j,m) if(in[i][j]==0) q.push(make_pair(i,j)),dp[i][j][1]=1;
    while(q.size())
    {
        int i=q.front().first,j=q.front().second;q.pop();
        rep(k,4) 
        {
            int x=i+dx[k],y=j+dy[k];
            if((x>=1&&x<=n&&y>=1&&y<=m)&&(a[i][j]==a[x][y]-1))
            {
                dp[x][y][2]=(dp[x][y][2]+dp[i][j][1])%mod;
				dp[x][y][3]=(dp[x][y][3]+dp[i][j][2])%mod;
				dp[x][y][4]=(dp[x][y][4]+dp[i][j][3]+dp[i][j][4])%mod;
                if(--in[x][y]==0) q.push(make_pair(x,y));
            }
        }
    }
}

int main()
{
    cin>>n>>m;
    rpp(i,n) rpp(j,m) cin>>a[i][j];
    rpp(i,n) rpp(j,m)
    {
        rep(k,4) 
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=1&&x<=n&&y>=1&&y<=m)
            {
                if(a[i][j]==a[x][y]-1) ++out[i][j];
                else if(a[i][j]==a[x][y]+1) ++in[i][j];
            }
        }
    }
    topo();
    ll ans=0;
    rpp(i,n) rpp(j,m) if(out[i][j]==0) ans=(ans+dp[i][j][4])%mod;
    cout<<ans<<endl;
    return 0;
}