| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3096 人关注过本帖, 1 人收藏
标题:分享三个好玩的小问题,有兴趣的可以弄弄看~
只看楼主 加入收藏
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
其实后面两题就是说同一样东西,只是第三题还要在第二题的基础上变通一下[如果长和宽分别为N和M的话,期待时间复杂度为o(N*N*M)]~

[此贴子已经被作者于2018-3-28 20:49编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-03-28 20:46
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
收藏
得分:7 
重在参与!第三题,以当前的输入为基准遍历,只是加入面积判断,对小于已得到的面积不做遍历。
不会计算复杂度,期待大神更优的算法。
程序代码:
#include <stdio.h>
int fun(int a[][100],int x,int y,int s)
{
    int i,j;
    for(i=0;i<x;i++)
    {
        for(j=0;j<y&&(x+1-i)*(y+1-j)>s;j++)
        {
            if(a[i][j]==a[x][y]&&a[x][j]==a[i][y])
                return (x+1-i)*(y+1-j);
        }
    }
    return s;
}
void main()
{
    int n,m,i,j,s,a[100][100];
    scanf("%d%d",&m,&n);
    for(i=s=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            scanf("%d",&a[i][j]);
            s=fun(a,i,j,s);
        }
    }
    printf("%d\n",s);
}


[此贴子已经被作者于2018-3-28 22:07编辑过]

2018-03-28 22:04
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 12楼 xzlxzlxzl
第二题是是用数组储存状态快速获取的对应值(类似利用散列表快速查找数据那样),这题是要确定两个数据综合起来判断,所以要设计一个快速同时获取两个数据状态的方法~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-03-28 22:16
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
收藏
得分:0 
回复 11楼 九转星河
经测试我12楼代码,如输入以下数据,是完全遍历,共遍历36次,是不是相当于小于你O(n*n*m)=O(4*4*4)=64的复杂度?
4 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
output:0
2018-03-28 22:27
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 14楼 xzlxzlxzl
其实好像和我那个算法遍历次数差不多,那个时间复杂度是个趋势,而不真的要完全遍历~
其实开一个1000*1000的二维数组(题目K数据范围是0<=K<=999)记录两个顶点的状态这样可以优化,但你那个算法可以减少运算量真的很厉害~

PS:我算过一下理论上我那个要遍历40次,首先遍历第一二行,(从左到右扫描就可以了,然后二三行,三四行,遍历的时候看看buf[a[i][j]][a[i][j+x]]的状态值是多少就可以了,所代表这样用了两个循环,然后外循环加一个一三行,二四行这样)~理论上算出是(16+12+8+4)=40次(比36要大一点,算是这样了)~

[此贴子已经被作者于2018-3-28 23:08编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-03-28 22:47
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
今晚晚点睡了,发现就算把楼主算法复杂度最多还是o(n^4),只是数据量比较少的时候看不出来,实际最多执行次数大约是(n^4)/4次~
输入12*12的时候完全遍历记得是5304次~

附上12楼记录次数的测试代码,输入14楼数据就是和所提供的36完全吻合~

程序代码:
#include <stdio.h>
static unsigned count;
int fun(int a[][100],int x,int y,int s)
{
    int i,j;

    for(i=0;i<x;i++)
    {
        for(j=0;j<y&&(x+1-i)*(y+1-j)>s;j++)
        {
            ++count;
            if(a[i][j]==a[x][y]&&a[x][j]==a[i][y])
                return (x+1-i)*(y+1-j);
        }
    }
    return s;
}
void main()
{
    int n,m,i,j,s,a[100][100];
    scanf("%d%d",&m,&n);
    for(i=s=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            scanf("%d",&a[i][j]);
            s=fun(a,i,j,s);
        }
    }
    printf("%d\n",s);
    
    printf("%u\n",count);
}




[此贴子已经被作者于2018-3-28 23:39编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-03-28 23:37
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
编辑掉~

[此贴子已经被作者于2018-3-29 02:31编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-03-29 01:51
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
这个不知道对不对
第三题
#include <stdio.h>
 main()
{
    int n,m,i,j,sum=0,a[200],max=0;
    scanf("%d%d",&m,&n);
    for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            scanf("%d",&a[i*m+j]);
        }
    }
    for(i=0;i<=(m-1)*(n-1);i++)
    {
        for(j=i+m+1;j<=m*n;j++)
        {
            if(a[i]==a[j]&&a[(j-i)%m+i]==a[(j-(j-i)%m)])
            {   
                sum=((j-i)%m+1)*((j-i)/m+1);   
            }
            if(sum>max)
            max=sum;
        }
    }
    printf("%d",max);
}

2018-03-29 11:45
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
/*第一题*/
#include <stdio.h>
int main()
{
    int *p,*q,m,k;
    printf("输入数组元素个数和差值大小:\n");
    scanf("%d %d",&m,&k);
    printf("输入数组每个元素的大小:\n");
    int a[m];
    for(int i=0;i<m;i++)
    scanf("%d",&a[i]);
    q=p=&a[0];
    while(q<=&a[m-1])
    {
        if(*p+k<*q)
        p++;
        else if(*p+k>*q)
        q++;
        else
        {
            printf("YES\n");
            break;   
        }
            
    }
    if(q>&a[m-1])printf("NO");
    return 0;
}
/*第二题*/
#include <stdio.h>
#include <string.h>
int main()
{
    int m,len,maxlen=0;
    printf("输入串长度\n");
    scanf("%d",&m);
    char a[50];
    int b[m];
    int set[2*m+1];
    memset(set,-1,sizeof(set));
    printf("输入串:\n");
    scanf("%s",a);
    for(int i=0;i<m;i++)
    {
        if(a[i]=='0')
        {
            
            if(i==0)
            b[i]=-1;
            else
            b[i]=b[i-1]-1;
        }
        if(a[i]=='1')
        {
            if(i==0)
            b[i]=1;
            else
            b[i]=b[i-1]+1;
        }
        if(set[b[i]+m]==-1)
            set[b[i]+m]=i;
        else
        {
            
            len=i-set[b[i]+m];
            if(len>maxlen)
            maxlen=len;
        }
    }
    printf("%d\n",maxlen);
    return 0;
}
2018-03-29 12:11
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
收藏
得分:0 
回复 16楼 九转星河
正确,其实我那代码循环嵌套4次了,就是O(N^4),傻瓜式的遍历。
2018-04-02 20:03
快速回复:分享三个好玩的小问题,有兴趣的可以弄弄看~
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.034047 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved