czl蒻蒟的OI之路16

  • XJOI奋斗群蒻蒟群群赛17 RANK排名9
      • T1Increasing SequenceTLE一次AC
          • 题意
          • 分析过程
          • 给出题解
      • T2Jumping JackWA一次后AC
          • 题意
          • 分析过程
          • 给出题解
      • T3How Many Squares 已AC
          • 题意
          • 分析过程
          • 给出题解
      • T4A Simple TaskWA两次之后AC
          • 题意
          • 分析过程
          • 给出题解
      • T5
          • 题意
          • 分析过程
          • 给出题解

—>XJOI奋斗群(蒻蒟群)群赛17<— RANK排名9

T1:Increasing Sequence(TLE一次AC)

题意:

给你一个数列,然后给出你一个数d,数列中的每个数都可以加上d,问你最少加上几次d,能够使这个数列变成一个增序序列。

分析过程:

只要每碰到一个数比前一个数小,就加上一定的值直到大于前一个数,最后输出次数就行了。

给出题解:
#include
using namespace std;

int main()
{
    int n,d;
    int a[5000];
    scanf("%d%d",&n,&d);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    long long  cnt=0;
    for(int i=2;i<=n;i++)
    {
        if(a[i]<=a[i-1])
        {
            int dif=a[i-1]-a[i];
            dif/=d;
            dif++;
            a[i]+=d*dif;
            cnt+=dif;
        }
        else continue;
    }
    printf("%d\n",cnt);
    return 0;
}

T2:Jumping Jack(WA一次后AC)

题意:

一个人在练习跳跃,第一次只能跳一个单位,之后每一次跳就能够比前一次长一个单位,问你经过多少次跳跃之后能够准确地到达x这个位置。

分析过程:

由于x的值可能是正的也可能是负的,所以要先把x取绝对值。先预估sqrt(2*x)的值作为cnt的预估值,然后再从这个值开始向答案推进。

给出题解:
#include
using namespace std;
int main()
{
    int x;
    scanf("%d",&x);
    x=abs(x);
    int cnt=sqrt(2*x);
    while(cnt*(cnt+1)/21)/2-x)&1)
    cnt++;
    printf("%d\n",cnt);
    return 0;
}

T3:How Many Squares? (已AC)

题意:

给你一个矩阵,问你其中有几个正方形,要求正方形旁边不能有多与的边。

分析过程:

先便利每个数组中的

给出题解:
#include
using namespace std;
int dic[8][2]= {{0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
char a[255][255];
int len=0;
int n,m;

void judge(int x,int y)
{
    if(x<0||x>=n||y<0||y>=m||a[x][y]!='1')return ;
    a[x][y]='2';
    len++;
    for(int i=0; i<8; i++)
    {
        judge(x+dic[i][0],y+dic[i][1]);
    }
}

bool solve(int x,int y,int len,int l,int r)
{
    for(int i=0; i1; i++)
        for(int j=l; jif(x+dic[j][0]*i<0||x+dic[j][0]*i>=n||y+dic[j][1]*i<0||y+dic[j][1]*i>=m||a[x+dic[j][0]*i][y+dic[j][1]*i]!='2')
                return 0;
        }
    return 1;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i"%s",a[i]);
        int res=0;
        for(int i=0; ifor(int j=0; j<m; j++)
            {
                if(a[i][j]=='1')
                {
                    len=0;
                    judge(i,j);
                    if(len%4)continue;
                    res+=solve(i,j,len/4,0,2)&&solve(i+len/4,j+len/4,len/4,2,4);
                    res+=solve(i,j,len/4,4,6)&&solve(i+len/2,j,len/4,6,8);
                }
            }
        printf("%d\n",res);
    }
    return 0;
}

T4:A Simple Task(WA两次之后AC)

题意:

给你一个简单的无向图,让你统计其中环的个数。

分析过程:

我们设计一个状态{[s][SET][i]}来记录起点s到终点i的简单路径的条数,其中SET表示经过的节点的集合。但由于圆排列的性质,这样的状态是有重复的。我们通过指定起点为SET中的最小序号点来消除圆排列带来的重复,状态变为{[SET][i]}。还要注意,即使这样定义状态,计算简单环个数的时候仍会将2个节点一条单边的情况当成环,也会将长度大于2的环正向计算一遍,反向计算一遍。所以我们还要进行后处理。

前向的状态转移方程可以写作:
dp[SET][j]=∑(i∈SET,i−j)dp[SET][i]
但这样的方程并不利于统计简单环的个数。

后向的状态转移方程可以写作:
设简单环的个数用统计量cnt表示。对于dp[SET][i]状态,i的每一条边eij,j∈neighbor(i):若j∈SET则说明遇到了环,dp[SET][i]贡献给cnt;若j∉SET则说明获得一条简单路径,dp[SET][i]贡献给dp[SET′][j]。

后处理:
由于长度为2的简单环被统计了进去,所以cnt−m;又由于长度大于2的简单环被统计了2遍,所以(cnt−m)/2。
最后要注意环的个数可能会达到19!个,所以我们需要用int64(之前被这个卡了好久)。

给出题解:
#include
using namespace std;
typedef long long ll;

ll n,m,ans,tot;
ll tmap[20][20],f[1<<19][19];

ll get_p(int a)
{
    for(int i=0; iif(a&(1<return i;
    }
}
ll solve()
{
    ll i,j,k,p,s;
    ans=0;
    tot=(1<1;
    memset(f,0,sizeof f);
    for(i=0; i//      printf("%d %d\n",1<
        f[1<1;
    }
    for(i=1; i<=tot; i++)
    {
        for(j=0; jif(f[i][j]==0) continue ;
            p=get_p(i);
            for(k=p; kif(j==k) continue ;
                if(tmap[j][k]==0)continue;
                if(i&(1<if(k==p) ans+=f[i][j];
                }
                else
                {
                    s=i|(1<2;
    return ans;
}
int main()
{
    scanf("%I64d%I64d",&n,&m);
    memset(tmap,0,sizeof tmap);
    ll u,v;
    for(int i=1; i<=m; i++)
    {
        scanf("%I64d%I64d",&u,&v);
        tmap[u-1][v-1]=tmap[v-1][u-1]=1;
    }
    ll res=solve();
    printf("%I64d\n",res);
    return 0;
}
}

T5:

题意:
分析过程:
给出题解:

你可能感兴趣的:(蒟蒻OI之路)