CodeForces #209 (Div. 2) A,B,D 解题报告

A.Table

题意:

        给了一个N*M的矩阵(3<=N,M<=50)...再给出一些矩阵上的点..现在能做的操作是将某个角与某个给定的点之间的区域都标记..问最少几步可以标记完整个区域

题解:

        若在边界上有点(题目保证四个角上没点)..则答案是2...否则是4

Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define oo 2000005
#define MAXN 4050000
#define pi acos(-1.0)
#define esp 1e-30
using namespace std;     
int main()
{    
       int n,m,y,x,t,ans; 
       scanf("%d%d",&n,&m);
       ans=4;
       for (y=1;y<=n;y++)
          for (x=1;x<=m;x++)
          {
                 scanf("%d",&t);
                 if (t && (y==1 || x==1 || y==n || x==m)) ans=2;
          }
       printf("%d\n",ans);
       return 0;
}

B.Permutation

题意:

        给了数字N(N<=50000)...请找出1~N的某个全排列满足...其中2k ≤ n

题解:

       对于初始的1,2,3....n..这个函数为0..然后翻转1,2...差距变成2..翻转3,4差距变成4...所以直接构造就好

Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define oo 1<<29
#define pi acos(-1.0)
#define MAXN 105005
#define esp 1e-30  
using namespace std;   
int main()
{    
       int n,k,i;    
       scanf("%d%d",&n,&k); 
       for (i=1;i<=n;i++)
          if (i<=k) printf("%d %d ",i*2,i*2-1);
              else  printf("%d %d ",i*2-1,i*2);
       printf("\n");
       return 0;
}

D.Pair of Numbers

题意:

        给了一列数N(1<=N<=3*10^5)...然后要找出一种区间[l,r]...其中有在[l,r]见的数是所有[l,r]数的约数...问最长的[l,r]有多长..并且有几个这么长的..起点分别在哪

题解:

       首先想到的是按数值从小往达的做..比如有2,能覆盖到一个6..那么这个6后面也没必要扫了...那是不是只要能扫到就把这个数标记到后面不扫了呢?

       看怎么一组列子: 2 6 3 9 12 6  , 如果从2标记..标记了1,2号位..会影响到3来找更长的...

       所以正确的处理是从小到大来扫.每次往左往右扫到无法整数倍的数或者出界..扫到一个数..则将其除掉这个当前来扫的数..对于1可以特殊考虑..而最小的扫的数就是2了..那么对于一个数最多被扫log(d)次..d是其数值..那么整个算法的复杂度就是nlog(d)了...


Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define oo 1<<29
#define pi acos(-1.0)
#define MAXN 300005
#define esp 1e-30
using namespace std;     
struct node
{
       int id,x,pre;
       bool operator <(node a) const
       {
               return x<a.x;
       }
}P[MAXN];
bool used[MAXN];
int a[MAXN],ans[MAXN];
int main()
{   
       int n,i,t,AL,x,l,r,num;  
       scanf("%d",&n);
       for (i=1;i<=n;i++) scanf("%d",&a[i]),P[i].id=i,P[i].x=P[i].pre=a[i]; 
       sort(P+1,P+1+n);
       AL=-1;
       for (t=1;t<=n;t++)
          if (P[t].x==a[P[t].id])
          {
                 if (P[t].x==1) { AL=n-1,ans[num=1]=1; break; }
                 x=P[t].x;
                 for (l=P[t].id-1;l>=1;l--) 
                    if (a[l]%x) break;
                           else a[l]/=x;
                 l++;
                 for (r=P[t].id+1;r<=n;r++)
                    if (a[r]%x) break;
                           else a[r]/=x; 
                 r--;
                 if (AL<r-l)
                 {
                       AL=r-l;
                       ans[num=1]=l;
                 }else
                 if (AL==r-l) ans[++num]=l;
          }
       printf("%d %d\n",num,AL);
       sort(ans+1,ans+1+num);
       for (i=1;i<=num;i++) printf("%d ",ans[i]);
       printf("\n");
       return 0;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值