codeforces #147(div2)

A 求h和m完全相同时最长的连续个数。。。

#include<stdlib.h> 
#include<string.h>
#include<math.h>
#define M   100010
int h[M],m[M]; 
int main()
{
 int n,k,i,j,c;
 while(scanf("%d",&n)!=EOF){
   c=1;  k=1; 
   scanf("%d %d",&h[0],&m[0]);
   for(i=1;i<n;i++){
     scanf("%d %d",&h[i],&m[i]);
     if(h[i]==h[i-1]&&m[i]==m[i-1]){ 
       k++;
  if(k>c)  c=k;
     }
     else  k=1;
   }
   printf("%d\n",c);
 }  
 //system("pause");
 return 0;    
}


B 此题不用考虑使操作数最少,只要控制在s步之内即可。易知,当表中的数从小到大排列时一定满足要求,所以我们可以先存储一张排好序的表,然后将输入表与排序表对照,便可得出需要swap的位置。。。

#include<stdio.h>
#include<stdlib.h> 
#include<string.h>
#include<math.h>
#define M   100010
int c[60];
struct oper
{
  int x1,y1;
  int x2,y2;       
}op[3000];
struct position
{
  int a;
  int x,y;     
}p[3000],q[3000];
int cmp(const void *a,const void *b){
    struct position *c=(struct position *)a;
    struct position *d=(struct position *)b;
    return c->a-d->a;
}
int main()
{
 int n,m,k,i,j,tmp,len;
 while(scanf("%d",&n)!=EOF){
   for(i=1;i<=n;i++)
     scanf("%d",&c[i]);
   k=0;
   for(i=1;i<=n;i++)
     for(j=1;j<=c[i];j++){
       scanf("%d",&p[k].a);
       p[k].x=i;   p[k++].y=j;
     }
   len=k;
   for(i=0;i<len;i++){
     q[i].a=p[i].a;  q[i].x=p[i].x;  q[i].y=p[i].y;                 
   }
   m=0;
   qsort(q,len,sizeof(q[0]),cmp); 
   for(i=0;i<len;i++){
     if(p[i].a!=q[i].a){
       for(j=i+1;j<len;j++){                   
         if(p[j].a==q[i].a){
           tmp=p[j].a;
           p[j].a=p[i].a;
           p[i].a=tmp;
           op[m].x1=p[i].x;  op[m].y1=p[i].y;
           op[m].x2=p[j].x;  op[m].y2=p[j].y;
           m++;      break;               
         }
       }
     }                                      
   }
   printf("%d\n",m);
   for(i=0;i<m;i++)
     printf("%d %d %d %d\n",op[i].x1,op[i].y1,op[i].x2,op[i].y2);
 }  
 return 0;    
}


C 素数打表,然后二分查找较省时。。。

#include<stdio.h>
#include<stdlib.h> 
#include<string.h>
#include<math.h>
#define M   1000010
#define Max(a,b)  (a>b)?a:b
int a,b,k;
int f[M],s[M],hash[M];

void init()           //素数打表 
{
  int i,j,k=0;
  memset(f,1,sizeof(f)); 
  memset(s,0,sizeof(s));   
  for(i=2;i*i<M;i++)
    for(j=i;j*i<M;j++)
      f[i*j]=0;            //i*j不是素数 
  f[1]=0;
  for(i=1;i<M;i++){
    s[i]=s[i-1];
    if(f[i]) s[i]++;         //前i个数中,素数的个数             
  }
  for(i=1;i<M;i++){  
    if(f[i])  hash[++k]=i;           //保存素数  
  }
}

//条件遍历法
int main()
{
 int a,b,k,n,m,i,j,ml,w;
 init(); 
 while(scanf("%d %d %d",&a,&b,&k)!=EOF){
   if(s[b]-s[a-1]<k)   printf("-1\n");
   else{
    ml=-1;
    for(i=a;hash[s[i-1]+k]<=b;i++){
      ml=Max(ml,hash[s[i-1]+k]-i+1);
      if(hash[s[i]+k]>b)
        w=b-i+1; 
    }
    ml=Max(ml,w);
    printf("%d\n",ml);
   }
 }
 //system("pause");
 return 0;    
}  

//二分法
int check(int mid)
{
  int i;
  for(i=a;i<=b-mid+1;i++)    
    if(s[i+mid-1]-s[i-1]<k)  return 0;
  return 1;
} 
int main()
{
 int n,m,i,j,ml,w;
 init(); 
 while(scanf("%d %d %d",&a,&b,&k)!=EOF){
   if(s[b]-s[a-1]<k)   printf("-1\n");
   else{
    int l,r,mid;
    ml=-1; l=1;  r=b-a+1;
    while(l<=r){
      mid=(l+r)>>1;
      if(check(mid)){            
        ml=mid;
        r=mid-1;           //缩小范围 
      }else  l=mid+1;      //扩大范围 
    }
    printf("%d\n",ml);
   }
 }
 //system("pause");
 return 0;    
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值