1. 程式人生 > >CF 1088(A , B , C , D)——思路

CF 1088(A , B , C , D)——思路

http://codeforces.com/contest/1088

A:Ehab and another construction problem

  輸出 2 和 n(偶數的話)或者 2 和 n-1(奇數的話)就行了。n==1的時候非法。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int x;
int main()
{
  scanf("%d",&x);
  if(x==1
)puts("-1"); else if(x&1)printf("%d %d\n",x-1,2); else printf("%d %d\n",x,2); return 0; }
View Code

B:Ehab and subtraction

  排序之後走一遍就行了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+5
; int n,k,a[N]; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)scanf("%d",&a[i]); sort(a+1,a+n+1); int p=1,tag=0; for(int i=1;i<=k;i++) { if(p>n){puts("0");continue;} printf("%d\n",a[p]-tag);tag=a[p]; for(p++;a[p]==tag&&p<=n;p++); }
return 0; }
View Code

C:Ehab and a 2-operation task

  如果升序的話,比如要弄成 0 , 1 , 2 , 3 , ... n-1 , k(k>=n),假設正在做第 i 個位置,那麼模數應該大於 i-1 ,如果之前都弄好了的話,這次取模就不會對之前造成影響了!

  所以一開始給每個位置加上足夠大的數(讓它的值 >= (i-1)*2+1),然後依次取模就行了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2005;
int n,a[N],tag;
int main()
{
  scanf("%d",&n);
  for(int i=1;i<n;i++)
    scanf("%d",&a[i]),tag=max(tag,(i-1<<1)+1-a[i]);
  scanf("%d",&a[n]);tag=max(tag,n-1-a[n]);
  if(tag)printf("%d\n1 %d %d\n",n,n,tag);
  else printf("%d\n",n-1);
  for(int i=1;i<n;i++)
    {
      printf("2 %d %d\n",i,a[i]+tag-(i-1));
    }
  return 0;
}
View Code

D:Ehab and another another xor problem

  因為最高位對大小影響比較大,所以從高到低位做;這樣能已經知道更高位的值,從而通過異或把更高位的影響消掉。

  然後就不太會了。想著在每一位上判斷 0 , 0 和 1 , 1 ,但無法通過2次來確定相等的話是同為0還是同為1。

  看了題解。原來是一開始先判一個 0 , 0 來了解哪個比較大;然後可以每一位判斷 0 , 1 和 1 , 0 ,這樣可以知道相等的話是同為0還是同為1,但無法知道不相等的話哪個是0哪個是1;這時只要利用一開始判斷出來的那個“哪個比較大”就能知道這一位上哪個是0哪個是1了!而且在判這一位的 0 , 1 和 1 , 0 時已經可以知道去掉這一位之後哪個比較大,就可以做下去了!

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=35;
int bin[N],a,b;
int main()
{
  bin[0]=1;for(int i=1;i<30;i++)bin[i]=bin[i-1]<<1;
  printf("? 0 0\n");fflush(stdout);
  int d; scanf("%d",&d);
  for(int t=29,x,y;t>=0;t--)
    {
      printf("? %d %d\n",a|bin[t],b);fflush(stdout);
      scanf("%d",&x);
      printf("? %d %d\n",a,b|bin[t]);fflush(stdout);
      scanf("%d",&y);
      if(x==y)
    {
      if(d==1)a|=bin[t]; else b|=bin[t];
      d=x;
    }
      else if(y==1)a|=bin[t],b|=bin[t];
    }
  printf("! %d %d\n",a,b);
  return 0;
}
View Code