题解

98 条题解

  • 2
    @ 2018-10-30 20:52:04
    //扩展知识:玩生命游戏的都是数学和生物大佬,他们天天煮汤
    //此题有两个坑点:m,n的顺序,读入的就是第一秒状态
    //之后进行模拟即可,t的范围未知,但我们可以用滚动数组压去一维
    #include<iostream>
    using namespace std;
    char map[1010][1010][2];
    int bx[8]={0,0,1,1,1,-1,-1,-1},by[8]={1,-1,-1,0,1,-1,0,1};
    int main()
    {
        int m,n,t,i,j,k,nx,ny,num,u;
        cin>>m>>n>>t;
        for(i=1;i<=n;i++)
         for(j=1;j<=m;j++)
          cin>>map[i][j][1];
        for(u=1;u<t;u++)
         for(i=1;i<=n;i++)
          for(j=1;j<=m;j++)
           {
            num=0;
            for(k=0;k<8;k++)
             {
                nx=i+bx[k];
                ny=j+by[k];
                if(nx<1||nx>n||ny<1||ny>m)
                 continue;
                if(map[nx][ny][u&1]=='1')
                 num++;
             }
            if(map[i][j][u&1]=='1')
             {
                if(num<2||num>3)
                 map[i][j][(u&1)^1]='0';
                else
                 map[i][j][(u&1)^1]='1';
             }
            else
             if(num==3)
              map[i][j][(u&1)^1]='1';
             else
              map[i][j][(u&1)^1]='0';
           }
        for(i=1;i<=n;i++)
         {
            for(j=1;j<=m;j++)
             cout<<map[i][j][t&1];
            cout<<endl;
         }
         return 0;
    }
    
  • 1
    @ 2020-10-14 09:35:51
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <deque>
    using namespace std;
    
    namespace dts
    {
        const int mx[8]={-1,-1,-1,0,0,1,1,1};
        const int my[8]={-1,0,1,-1,1,-1,0,1};
        
        struct sta
        {
            vector<vector<int>> mat;
            
            void set_size(int n,int m)
            {
                mat.resize(n);
                for (int i=0;i<n;i++)
                    mat[i].resize(m,0);
            }
            
            sta next()
            {
                sta ans;
                int n=mat.size(),m=(mat.size()==0)?0:mat[0].size();
                ans.set_size(n,m);
                for (int i=0;i<n;i++)
                    for (int j=0;j<m;j++)
                    {
                        int cnt=0;
                        for (int k=0;k<8;k++)
                            if (0<=i+mx[k]&&i+mx[k]<n&&0<=j+my[k]&&j+my[k]<m)
                                cnt+=mat[i+mx[k]][j+my[k]];
                        if (cnt<2||cnt>3)
                            ans.mat[i][j]=0;
                        else if (cnt==3)
                            ans.mat[i][j]=1;
                        else
                            ans.mat[i][j]=mat[i][j];
                    }
                return ans;
            }
        };
        
        int M,N,T;
        sta statu;
        
        void main()
        {
            while (~scanf("%d%d%d\n",&M,&N,&T))
            {
                statu.set_size(N,M);
                for (int i=0;i<N;scanf("\n"),i++)
                    for (int j=0;j<M;j++)
                    {
                        char temp;
                        scanf("%c",&temp);
                        statu.mat[i][j]=temp-'0';
                    }
                for (int i=1;i<T;i++)
                    statu=statu.next();
                for (int i=0;i<N;printf("\n"),i++)
                    for (int j=0;j<M;j++)
                        printf("%d",statu.mat[i][j]);
            }
        }
    }
    
    int main()
    {
        dts::main();
    }
    
  • 0
    @ 2017-11-07 19:36:53

    题目太坑人,说好的“n行m列”,竟然先输m后输n

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    bool now[1005][1005];
    bool nxt[1005][1005]; 
    inline int calc(int x,int y){
        int ret=0;
        if(now[x-1][y-1])ret++;
        if(now[x-1][y])ret++;
        if(now[x-1][y+1])ret++;
        if(now[x][y-1])ret++;
        if(now[x][y+1])ret++;
        if(now[x+1][y-1])ret++;
        if(now[x+1][y])ret++;
        if(now[x+1][y+1])ret++;
        return ret;
    }
    int main(){
        int n,m,T;
        scanf("%d%d%d",&m,&n,&T);
        for(int i=1;i<=n;i++){
            getchar();
            for(int j=1;j<=m;j++){
                char x=getchar();
                if(x=='1')now[i][j]=1;
            }
        }
        while(--T){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    int a=calc(i,j);
                    if(a==2&&now[i][j])nxt[i][j]=1;
                    else if(a==3)nxt[i][j]=1;
                    else nxt[i][j]=0;
                }
            }
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    now[i][j]=nxt[i][j];
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(now[i][j])printf("1");
                else printf("0");
            }
            printf("\n");
        }
        return 0;
    }
    
  • 0
    @ 2017-10-07 21:05:58

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cstring>
    #define maxa 1000+10
    #define FOR(i,x,y) for(i=x;i<=y;++i)
    using namespace std;
    int a[maxa][maxa],b[maxa][maxa];
    string s;
    int main()
    {
    int m,n,t,i,j;
    cin>>m>>n>>t;
    FOR(i,1,n){
    cin>>s;
    FOR(j,1,m)
    {
    a[i][j] = s[j-1]-'0';
    }
    }

    int p,q,k;
    FOR(k,2,t)
    {
    memset(b,0,sizeof(b));
    FOR(i,1,n){
    FOR(j,1,m)
    {
    int tot = 0;
    int dx,dy;
    FOR(p,-1,1)
    FOR(q,-1,1)
    if(!(p==0&&q==0))
    {
    dx = i+p;
    dy = j+q;
    if(dx<1||dx>n||dy<1||dy>m)
    continue;
    if(a[dx][dy]==1)
    tot++;
    }
    if(a[i][j])
    {
    if(tot>3)
    b[i][j] =1;
    else if(tot==2||tot==3)
    b[i][j] = 0;
    else
    b[i][j] = 1;
    }
    else
    {
    if(tot==3)
    b[i][j] =1;
    else
    b[i][j] = 0;
    }
    }
    }
    FOR(i,1,n)
    FOR(j,1,m)
    if(b[i][j])
    {
    a[i][j] = 1-a[i][j];
    }
    }
    FOR(i,1,n)
    {
    FOR(j,1,m)
    {
    cout<<a[i][j];
    }
    cout<<endl;
    }
    }

  • 0
    @ 2016-09-27 19:49:52

    var a,b,f:array[0..1000,0..1000]of longint;
    i,j,l,n,m,t:longint; c:char;
    function check(x,y:longint):longint;
    var i,j,k:longint;
    begin
    k:=0;
    for i:=x-1 to x+1 do
    for j:=y-1 to y+1 do
    if a[i,j]=1 then inc(k);
    if a[x,y]=1 then dec(k);
    exit(k);
    end;
    begin
    readln(m,n,t);
    for i:=1 to n do
    begin
    for j:=1 to m do
    begin
    read(c);
    a[i,j]:=ord(c)-48;
    end;
    readln;
    end;
    for l:=1 to t-1 do
    begin
    b:=a;
    for i:=1 to n do
    for j:=1 to m do
    f[i,j]:=check(i,j);
    for i:=1 to n do
    for j:=1 to m do
    begin
    if (f[i,j]<2)and(a[i,j]=1) then b[i,j]:=0;
    if (f[i,j]>3)and(a[i,j]=1) then b[i,j]:=0;
    if (f[i,j]=3)and(a[i,j]=0) then b[i,j]:=1;
    end;
    a:=b;
    end;
    for i:=1 to n do
    begin
    for j:=1 to m do
    write(a[i,j]);
    writeln;
    end;
    end.

    注意读入是(m,n),被卡了一次...
    注意开始状态就是第一秒状态,被卡了一次...
    剩下的就是模拟了

  • 0
    @ 2014-10-15 18:26:02

    #include<iostream>
    using namespace std;
    main()
    {
    char c[1000][1000],o[1000][1000];
    int r,l,t,i,k,a,b;
    cin>>l>>r>>t;
    for(i=0;i<r;i++)
    cin>>c[i];
    for(;t>1;t--)
    {
    for(i=0;i<r;i++)
    for(k=0;k<l;k++)
    o[i][k]=0;
    for(i=0;i<r;i++)
    for(k=0;k<l;k++)
    if(c[i][k]=='1')
    for(a=i-1;a<=i+1;a++)
    {
    if(a<0||a>=r)
    continue;
    for(b=k-1;b<=k+1;b++)
    {
    if(b<0||b>=l||(a==i&&b==k))
    continue;
    o[a][b]++;
    }
    }
    for(i=0;i<r;i++)
    for(k=0;k<l;k++)
    if(c[i][k]=='1')
    {
    if(o[i][k]<2||o[i][k]>3)
    c[i][k]='0';
    }
    else
    if(o[i][k]==3)
    c[i][k]='1';
    }
    for(i=0;i<r;i++)
    cout<<c[i]<<endl;
    }

  • 0
    @ 2014-08-10 15:35:25

    #include <stdio.h>
    char cells[1000][1000];
    char count[1000][1000];
    int row,column,time;

    void add(int x,int y);
    int main(){
    int i,k;
    scanf("%d %d %d",&column,&row,&time);
    for(i=0;i<row;i++)
    scanf("%s",cells[i]);
    for(;time>1;time--){
    for(i=0;i<row;i++)
    for(k=0;k<column;k++)
    count[i][k]=0;
    for(i=0;i<row;i++){
    for(k=0;k<column;k++){
    if(cells[i][k]=='1')
    add(i,k);
    }
    }
    for(i=0;i<row;i++){
    for(k=0;k<column;k++){
    if(cells[i][k]=='1'){
    if(count[i][k]<2 || count[i][k]>3)
    cells[i][k]='0';
    }else{
    if(count[i][k]==3)
    cells[i][k]='1';
    }
    }
    }
    }
    for(i=0;i<row;i++)
    printf("%s\n",cells[i]);
    return 0;
    }
    void add(int x,int y){
    int i,k;
    for(i=x-1;i<=x+1;i++){
    if(i<0 || i>=row)
    continue;
    for(k=y-1;k<=y+1;k++){
    if(k<0 || k>=column || (i==x && k==y))
    continue;
    count[i][k]++;
    }
    }
    }

    以前写过一个扫雷,照搬过来了

  • 0
    @ 2013-11-08 11:25:48

    var
    a:array[0..1,0..1000,0..1000] of char;
    i,j,k,n,m,t,p,s:longint;
    begin
    readln(m,n,t);
    for i:=1 to n do
    begin
    for j:=1 to m do
    read(a[0,i,j]);
    readln;
    end;
    p:=0;
    for k:=1 to t-1 do
    begin
    p:=1-p;
    for i:=1 to n do
    for j:=1 to m do
    begin
    s:=0;
    if a[1-p,i-1,j]='1' then inc(s);
    if a[1-p,i,j-1]='1' then inc(s);
    if a[1-p,i+1,j]='1' then inc(s);
    if a[1-p,i,j+1]='1' then inc(s);
    if a[1-p,i-1,j-1]='1' then inc(s);
    if a[1-p,i-1,j+1]='1' then inc(s);
    if a[1-p,i+1,j-1]='1' then inc(s);
    if a[1-p,i+1,j+1]='1' then inc(s);
    if a[1-p,i,j]='1' then
    begin
    if (s<2) or (s>3) then a[p,i,j]:='0'
    else a[p,i,j]:='1';
    end
    else
    begin
    if s=3 then a[p,i,j]:='1'
    else a[p,i,j]:='0';
    end;
    end;
    end;
    for i:=1 to n do
    begin
    for j:=1 to m do
    write(a[p,i,j]);
    writeln;
    end;
    end.

    开个滚存,但是第一次却WA了
    因为n,m读反了!
    大家注意!!!

  • 0
    @ 2013-08-27 11:15:17

    范围是 100 100 64

  • 0
    @ 2013-07-31 21:33:36

    出题的真坑啊,样例出个好的我就不会要交两次了,
    1.范围不知道,我开的10010~~~
    2.给出的状态及为第一秒(被坑惨了,调了我好长时间)
    3.m,n输入顺序我倒注意了
    4.如果下次大牛们发题解不发程序只发思路,就更好了!

  • 0
    @ 2012-10-07 11:49:44

    总结下:

    1、数组范围要开大。0..101是最小范围了!

    2、T,数据给出的状态就是第1秒状态,那么T秒时状态就是变换T-1次后的状态,只需T-1次!

    3、滚动数组。开两个数组,因为一个细胞的改变会引起其他细胞改变,需要换其他数组存储新状态。不过楼下有位神牛用一个数组使用巧妙的方法也过掉了。

    4、判断问题。如果你用了两个数组,没赋初值,那么判断时一定要面面俱到。if (a=1) if (tot=2||tot=3) b=1 else b=0一定要有else!

    5、书写错误请静态查错。比如const存储方向那么使用方向和判断越界时xy写反、范围nm写反等等

    6、读入错误。先读入m后读入n,不要被题目n*m所迷惑。

    7、有谁像我一样用int类型读入状态?char!string!

  • 0
    @ 2009-11-04 21:32:45

    for k:=2 to t do

    记住,是2!

  • 0
    @ 2009-11-03 18:35:17

    同楼下。

    很晕很晕,那个被调反的 N 和 M ,

    我后来滚动还错了……

    AC率秒降

  • 0
    @ 2009-10-18 17:04:50

    n和m是反的

    出题人闹坑

    还有数组开100会wa

    要开101 数据范围也有问题

  • 0
    @ 2009-10-10 18:16:01

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    粗心呀,第一次提交时打错好几个变量名,居然还得了20分!!!

    ===================晒程序=====================

    Program Game;

    Var

    f, a, b: Array[0..200, 0..200]Of Integer;

    n, m, t: Integer;

    i, j: Integer;

    ch: Char;

    Procedure Main;

    Var

    i, j, k: Integer;

    Begin

    For i := 1 To n Do

    For j := 1 To m Do

    Begin

    k := a[i, j];

    If k = 1 Then

    Begin

    If f[i, j] < 2 Then a[i, j] := 0

    Else If f[i, j] > 3 Then a[i, j] := 0;

    End Else If k = 0 Then

    Begin

    If f[i, j] = 3 Then a[i, j] := 1;

    End;

    If k > a[i, j] Then

    Begin

    Dec(b[i-1, j]); Dec(b[i+1, j]);

    Dec(b[i, j-1]); Dec(b[i, j+1]);

    Dec(b[i-1, j-1]); Dec(b[i-1, j+1]);

    Dec(b[i+1, j-1]); Dec(b[i+1, j+1]);

    End Else If k < a[i, j] Then

    Begin

    Inc(b[i-1, j]); Inc(b[i+1, j]);

    Inc(b[i, j-1]); Inc(b[i, j+1]);

    Inc(b[i-1, j-1]); Inc(b[i-1, j+1]);

    Inc(b[i+1, j-1]); Inc(b[i+1, j+1]);

    End;

    End;

    End;

    Begin

    FillChar(a, SizeOf(a), 0);

    FillChar(f, SizeOf(f), 0);

    ReadLn(m, n, t);

    For i := 1 To n Do

    Begin

    For j := 1 To m Do

    Begin

    Read(ch);

    a[i, j] := Ord(ch)-48;

    End;

    ReadLn;

    End;

    For i := 1 To n Do

    For j := 1 To m Do

    Begin

    f[i, j] := a[i-1, j] + a[i+1, j]

    +a[i, j-1] + a[i, j+1]

    +a[i-1, j-1] + a[i-1, j+1]

    +a[i+1, j-1] + a[i+1, j+1];

    b[i, j] := f[i, j];

    End;

    For i := 2 To t Do

    Begin

    Main;

    f := b;

    End;

    For i := 1 To n Do

    Begin

    For j := 1 To m Do Write(a[i, j]);

    WriteLn;

    End;

    End.

  • 0
    @ 2009-10-09 09:51:03

    t=1 居然是一次都不变 无语

  • 0
    @ 2009-09-06 13:53:12

    流动的水没有形状,漂流的风没有踪迹,一切OI题都取决于心!

    今天先在这里做一个百题留念!

    这道题开两个数组模拟更新即可!

    第930个AC这道题的,是一个身体虽是小孩,但头脑却是大人,他的名字就是wyc4662

    ……………………程序清单……………………

    var a,a2:array[0..101,0..101] of char;

    l,m,n,t,g,h,k:integer;

    begin

    readln(m,n,t);

    for g:=1 to n do begin

    for h:=1 to m do read(a[g,h]);{a数组为上一秒的状态,a2是当前秒的状态}

    readln;

    end;

    for l:=2 to t do begin

    for g:=1 to n do

    for h:=1 to m do begin

    k:=0;

    if a[g-1,h]='1' then k:=k+1;

    if a[g-1,h-1]='1' then k:=k+1;

    if a[g,h-1]='1' then k:=k+1;

    if a[g+1,h]='1' then k:=k+1;

    if a[g+1,h+1]='1' then k:=k+1;

    if a[g,h+1]='1' then k:=k+1;

    if a[g-1,h+1]='1' then k:=k+1;

    if a[g+1,h-1]='1' then k:=k+1;{以上8句话检查细胞(g,h)身边的存活细胞数k}

    if a[g,h]='1' then

    if (k>=2) and (k

  • 0
    @ 2009-08-25 18:44:00

    强烈鄙视楼主啊...

    给个水样例题意又不讲清楚

  • 0
    @ 2009-08-23 09:54:15

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    小心,n和m啊

    ---|---|---|---|---|---|---|---|---|-

    #include

    #include

    const int dx[8]={1,-1,0,0,-1,-1,1,1},dy[8]={0,0,1,-1,-1,1,-1,1};

    int ans[551][551],tie[551][551];

    int n,m,t;

    int main()

    {

    memset(ans,255,sizeof(ans));memset(tie,255,sizeof(tie));

    scanf("%d%d%d\n",&m,&n,&t);

    char st;

    for(int i=1;i

  • 0
    @ 2009-08-21 16:47:25

    这道water program我交了6次,以下是流程图:

    1:没开2个数组,一个是当前秒,一个是下一秒+数组范围应为0..101,0..101而不是0..100,0..100(范围开错显示WA而不是超范围···)

    2~5:数组范围定小了

    6:

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    强烈鄙视这道题猪一样的样例

    于是,我以我血淋淋的教训提醒大家:

    数组范围一定不要开小啊!!!!!!!!!

    数组范围一定不要开小啊!!!!!!!!!

    数组范围一定不要开小啊!!!!!!!!!

    数组范围一定不要开小啊!!!!!!!!!

信息

ID
1415
难度
6
分类
模拟 点击显示
标签
(无)
递交数
1867
已通过
517
通过率
28%
被复制
3
上传者