第二周CF13/07/19

A. Flipping Game


就A了AB题

第一眼看到这题,就想到直接暴搜,但很怕会超时,所以没敢做,然后一直再推,看有什么规律,后面发现很难找,见别人暴搜过了,我才敢写唉~WA了好多次

代码:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
int a[105];
int main()
{
    int n,i,j,sum=0,s,k,mmax=0;
    scanf("%d",&n);
    for(i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    for(i=1; i<=n; i++)
    {
        for(j=i; j<=n; j++)
        {
            s = sum;
            for(k=i; k<=j; k++)
            {
                s -= a[k];
                s += (1-a[k]);
                if(s>mmax) mmax = s;
            }
        }
    }
    printf("%d\n",mmax);
    return 0;
}


B. Hungry Sequence

直接筛选素数输出

代码:
#include <iostream>//B
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
const int M=10000001;
int p[M];
int s[M];
int main()
{
    int n,i,j,l=0;
    p[1]=1;
    for(i=2;i<=M;i++)
    {
      if(!p[i])
      {
          s[l++]=i;
          for(j=2*i;j<=M;j+=i)
          {
              p[j]=1;
          }
      }
    }
    cin>>n;
    for(i=0;i<n-1;i++)
    {
        printf("%d ",s[i]);
    }
    printf("%d",s[n-1]);
    return 0;
}

C. Magic Five

细推就可以推出一个公式(2^(k*l)/(2^l-1)*sum, sum=sum+2^i(i为0或5的位置),其实就是一个等比数列的求和,但是数据量很大,必须用快速取幂的方法,另外对等比数列,仔细观察,发现

T[n]=T[n/2]+T[n/2]*2^(n/2)......当n%2==0时

T[n]=T[n/2]+T[n/2]*2^(n/2)+2^n......当n%2==1时

代码:

#include <iostream>//C
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
const int M=100001;
const long long C=1e9+7;
char s[M];
long long sum,q;
int l;
int  powmode(int a,__int64 b)//快速幂取余
{
    if(b==0)return 1;
    if(b==1)return a;
    __int64 tmp=powmode(a,b/2)%C;
    tmp=tmp*tmp%C;
    if(b%2==1)tmp=tmp*a%C;
    return (int)tmp;
}
int fun(long long n)
{
   if(n==1)return sum;
    __int64 tmp=fun(n/2);
    tmp=(tmp+tmp*powmode(q,n/2))%C;
    if(n%2)tmp=(tmp+powmode(2,(n-1)*l)*sum%C)%C;
    return (int)tmp;
}
int main()
{
    int k,i;
   int ans;
    while(scanf("%s %d",s,&k)!=EOF)
    {
        l=strlen(s);
       ans=sum=0;
       q=powmode(2,l)%C;
        for(i=0; i<l; i++)
        {
            if(s[i]=='0' || s[i]=='5')
            {
                   sum=(sum+powmode(2,i))%C;
            }
        }
        ans=fun(k);
       cout<<ans<<endl;
   }
    return 0;
}

D. Block Towe r

给出n*m的格子,可以在空地上建房子,蓝色的房子可以住100个人,红色的房子可以住200个人,如何建房子使得能够住的人最多,并且要求红房子必须建在蓝色房子旁边,即有公共边。

画一个格子分析一下,发现只要用DFS搜索,搜到不能再走时那个点必须是红色的,也就是思路是,和周边公共边最多的那个格子最好是建蓝色房子,那么它的周边就可以全部建红色了(只要是空地)。

刚开始没有想到这个,想着只要找到一个空地,然后遍历它的周围,只要还有空地的,就在它这里建红房子,但是得出来不是最优,人数不是最大的。

代码:

#include <iostream>//D
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
const int M=100001;
struct node
{
    int x,y;
    char cr;
} a[5000005];
int n,m;
int dis[4][2]= {{1,0},{0,-1},{-1,0},{0,1}};
int vis[505][505];
char g[505][505];
int num;
int l;
bool inside(int x,int y)
{
    if(x<1 || x>n || y<1 || y>m)
        return false;
    return true;
}

void dfs(int x,int y)
{
    int i;
    num++;
    vis[x][y]=1;
    for( i=0; i<4; i++)
    {
        int fx=x+dis[i][0];
        int fy=y+dis[i][1];
        if(inside(fx,fy) && g[fx][fy]=='.' && vis[fx][fy]==0)
            dfs(fx,fy);//一直没法往下找时退回,那个点应置为红色
    }
    if(num>1)
    {
        a[l].x=x;
        a[l].y=y;
        a[l].cr='D';
        l++;
        a[l].x=x;
        a[l].y=y;
        a[l].cr='R';
        l++;
        g[x][y]='R';
    }
    num--;
}
int main()
{
    memset(vis,0,sizeof(vis));
    int i,j;
    char data;
    scanf("%d%d",&n,&m);
    l=0;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
        {
            cin>>data;
            g[i][j]=data;
            if(g[i][j]=='.')
            {
                a[l].cr='B';
                a[l].x=i;
                a[l].y=j;
                l++;
            }
        }
    }
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
        {
            if(vis[i][j]==0 && g[i][j]=='.')
            {
                num=0;
                dfs(i,j);
            }
        }
    }
    cout<<l<<endl;
    for(i=0; i<l; i++)
        printf("%c %d %d\n",a[i].cr,a[i].x,a[i].y);
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值