codeforces round237 DIV2

   p1:Valera and X

判断矩阵是否形同X,形同X就是对角线上元素相同,,其他位置上的所有元素相同并且不同于对角线上的元素。直接模拟判断...

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
char s[440][440];
int n;
int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for (int i=0; i<n; i++)
    scanf("%s",s[i]);
    bool ok1=true;
    bool ok2=true;
    for (int i=1; i<n; i++)
    {
        if (s[i][i]!=s[i-1][i-1]) ok1=false;
    }
    for (int i=1; i<n; i++)
    {
        if (s[i][n-i-1]!=s[i-1][n-i]) ok1=false;
    }
    if (!ok1) puts("NO");
    else
    {
        if (s[0][0]==s[0][1])
        {
            ok2=false;
        }

        s[0][0]=s[0][n-1]=s[0][1];
        for (int i=1; i<n; i++)
        {
            s[i][i]=s[i-1][i-1];
        }
        for (int i=1; i<n; i++)
        {
            s[i][n-i-1]=s[i-1][n-i];
        }
        for (int i=0; i<n; i++)
         for (int j=0; j<n; j++)
         if (s[i][j]!=s[0][0])
         {
             ok2=false;
             break;
         }

         if (ok2) puts("YES");
    else puts("NO");
    }

    return 0;
}

P2: Marathon

在一个正方形的跑道上逆时针跑步,边长a,给出d,n,对于1...n每一个i,求出跑i*d的距离时,所在位置的坐标(定义左下角是(0,0))。由于给的数保证小数点后不超过4位,所以可以直接乘10W或者100W化成整数来做,那么剩下的问题就是对一个长度,求出在正方形上的位置了,取模后判断一下就行..

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
double a,d;
ll aa,dd,n;
const int fx[4]={1,0,-1,0};
const int fy[4]={0,1,0,-1};
double eps=0.000000001;
void pos(ll len,ll &x, ll &y)
{
    len%=(aa*4);
    if (len<=aa)
    {
        x=len;
        y=0;
    }
    else
    if (len>aa && len<=aa*2)
    {
        x=aa;
        y=len-aa;
    }
    else
    if (len>aa*2 && len<=aa*3)
    {


            x=aa-(len-2*aa);
            y=aa;

    }
    else
    {
        len=4*aa-len;
        x=0;
        y=len;
    }
}
int main()
{
    scanf("%lf%lf",&a,&d);
    aa=(a+eps)*(1000000.0);
    dd=(d+eps)*(1000000.0);
    scanf("%d",&n);
    ll x=0,y=0;
    int dr=0;
    double xx,yy;
    for (int i=1; i<=n; i++)
    {
        pos(i*d*1000000,x,y);
        xx=x/1000000.0;
        yy=y/1000000.0;
        printf("%.6lf %.6lf\n",xx,yy);
    }
    return 0;
}

P3: Restore Graph

给以的数组D[],D[i]表示某个点到i的最短路,给出k,构造出最短路符合要求并且每个点连的边不超过k的原图...

下意识感觉可以插成一棵树,这样的话记录一下每个距离都有哪些节点,控制好每个节点的边数,一层一层的BFS就好,因为是一棵树,所以最后ans一定等于n-1,要么就是无解了..另外注意特判D数组,D数组有且只能有1个0...我只判断了大于1个的情况,结果复测挂在D数组没有0的情况了.....

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=101000;

int n,m,k;
int d[maxn];
        vector<int> g[maxn];
        vector<int> b[maxn];
int main()
{
//    freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&k))
    {
        int st=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&d[i]);
            b[d[i]].push_back(i);
            if (!d[i]) st=i;
        }
        bool ok=true;
         queue<int> q;
        q.push(st);
        int cc=1;
        int i=0,j=0;
        int ans=0;

        if (b[0].size()!=1)
        {
            cout<<"-1"<<endl;
            continue;
        }
        while(!q.empty())
        {
            while( !q.empty() && d[q.front()]<cc-1) q.pop();
            if (q.empty()) break;
            int ct=k-1;

            int u=q.front();
            if (u==st) ct++;
            q.pop();
            if (d[u]>=cc)
            {
                ok=false; break;
            }
            for (i; i<b[cc].size()&&ct; i++,ct--)
            {
                g[u].push_back(b[cc][i]);
                ans++;
                q.push(b[cc][i]);
            }
            if (i==b[cc].size())
            {
                cc++;
                i=0;
            }
        }

        if (!ok || ans<n-1 || b[0].size()>1)
        {
            cout<<"-1"<<endl;
        }
        else
        if (ans)
        {
            cout<<ans<<endl;
            for (int i=1; i<=n; i++)
            for (int j=0; j<g[i].size(); j++)
            {
                if (i<=g[i][j])  cout<<i<<" "<<g[i][j]<<endl;
                else   cout<<g[i][j]<<" "<<i<<endl;
            }
        }
        else cout<<"-1"<<endl;
    }

    return 0;
}

P4:Minesweeper 1D

给出一个一维的扫雷状态,求有多少种符合要求的填充方法...

对于0,1,2,*,可以看成4中状态,另外1还要分成1左边有雷和右边有雷两种情况,所以一共就是5种状态了..

0,1,2,3,4分别对应0,1左边有雷,1右边有雷,2,雷,

那么有状态转移方程:

            dp[0][i]=dp[0][i-1]+dp[1][i-1];
            dp[1][i]=dp[4][i-1];
            dp[2][i]=dp[1][i-1]+dp[0][i-1];
            dp[3][i]=dp[4][i-1];
            dp[4][i]=dp[2][i-1]+dp[3][i-1]+dp[4][i-1];

最后统计一下dp[0][n-1]+dp[1][n-1]+dp[4][n-1]的答案。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=1100000;
const int mod=1000000007;
ll dp[6][maxn];
int n,m;
char s[maxn];
inline int idx(int p)
{
    if (s[p]=='*') return 4;
    else if (s[p]=='2') return 3;
    else if (s[p]=='0') return 0;
    else if (s[p]=='1')
    {
        if (p==0 || s[p-1]=='*') return 1;
        else if (p==n-1 || s[p+1]=='*') return 2;
        else return 5;
    }
}
int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%s",s);
    n=strlen(s);
    memset(dp,0,sizeof dp);
    if (s[0]=='?')
    {
        dp[0][0]=dp[2][0]=dp[4][0]=1;
        dp[1][0]=dp[3][0]=0;
    }
    else
    {
        if (s[0]=='0') dp[0][0]=1;
        else if (s[0]=='1') dp[2][0]=1;
        else if (s[0]=='*') dp[4][0]=1;
    }
    for (int i=1; i<n; i++)
    {
        if (s[i]=='?')
        {
            dp[0][i]=dp[0][i-1]+dp[1][i-1];
            dp[1][i]=dp[4][i-1];
            dp[2][i]=dp[1][i-1]+dp[0][i-1];
            dp[3][i]=dp[4][i-1];
            dp[4][i]=dp[2][i-1]+dp[3][i-1]+dp[4][i-1];
        }
        else
        {
            if (s[i]=='0') dp[0][i]=dp[0][i-1]+dp[1][i-1];
            else if (s[i]=='1') dp[1][i]=dp[4][i-1],dp[2][i]=dp[1][i-1]+dp[0][i-1];
            else if (s[i]=='2') dp[3][i]=dp[4][i-1];
            else if (s[i]=='*') dp[4][i]=dp[2][i-1]+dp[3][i-1]+dp[4][i-1];
        }
        for (int j=0; j<5; j++)
        if (dp[j][i]>mod) dp[j][i]%=mod;
    }
    ll ans=0;
    ans=dp[0][n-1]+dp[1][n-1]+dp[4][n-1];
    ans%=mod;
    cout<<ans<<endl;
    return 0;
}

P5:Maze 1D

题意都还没看懂....来日再补...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值