USACO3.2 还是暴力+bitset学习

道阻且长

fact

一开始惯性思维以为是求位数…

后来发现是求最后一位非零

再连错两次是因为…保留位数少了…就是倒数的一些位数都会对最后以为有影响

ratios

炒鸡水的一道枚举居然错了这么多遍..罪过罪过

每一遍都是没有仔细考虑0..

第一遍除零爆

第二遍0的倍数不能是其它数

第三遍0不能是其它数的倍数QAQ…

翻nocow它说是..高斯消元…?!!!克莱姆法则….?!!!gcd//!!!

最后..几个相似的东西能写成数组就别写成三个呐..

msquare

魔方..以前在sicily做过..还是被sample坑了一次才过

int ord[]={7,2,6,4,3,1,5,0};//打顺序表
inline int trans(int p){
    int sum=0;
    for (int pos=7; pos>=0; pos--) {
        aim[pos]=p%10;
        p/=10;
    }
    for (int p=7; p>=0; p--) {
        sum=sum*10+aim[ord[p]];
    }
    return sum;
}

map水掉了本来应该用的康拓展开

*spin

暴力

但是却没想到可以如此暴力

(暴力破解线段树呐)

/* mark all the degrees we can see through wheel w */
void mark_light(int w)
 {
  int lv, lv2; /* loop variables */
  int wpos; /* wedge position */

  for (lv = 0; lv < 5; lv++)
   {
    if (wedglen[w][lv] < 0) /* no more wedges for this wheel */
      break;

    /* start of wedge */
    wpos = (pos[w] + wedgest[w][lv]) % 360;

    for (lv2 = 0; lv2 <= wedglen[w][lv]; lv2++)
     { /* throughout extent of wedge */
      light[wpos] |= (1 << w); /* mark as hole in wheel */
      wpos = (wpos + 1) % 360; /* go to the next degree */
     }
   }
 }

*kimbits

  • 一定不要去迎合答案而修改顺序.往往会越改越错

  • bitset使用

  • string temp =bitset<64>(num).to_string();
      while (temp.size()>len) {
          temp.erase(temp.begin());
      }
  • 注意int溢出

  • 一个优化

  • long long pow2[35]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296};
    
    long long allright = pow2[maxone+1];
      if (ord<allright) {
          num=ord-1;
      }
    //更简单的实现...
    long a[40]={0};
    while(ans>0){
    a[++a[0]]=ans&1;
    ans>>=1;
    }

  • 然后发现就是一个递推…

  • 不想水掉 晚点再做.

  • 还是没思路

    杨辉三角+从左往右递推

    void
    printbits(int nbits, int nones, double index)
    {
    double s;
    
    if(nbits == 0)
    return;
    
    s = sizeofset[nbits-1][nones];//不用叠加上来!!!!
    if(s <= index) {
    fprintf(fout, "1");
    printbits(nbits-1, nones-1, index-s);
    } else {
    fprintf(fout, "0");
    printbits(nbits-1, nones, index);
    }
    }
  • 忘了是哪里要求二进制位数了

    • 看到一段魔性代码

    • unsigned long CountBit(unsigned long X)
      {
      X = (X & 0x55555555) + (X >> 1 & 0x55555555);
      X = (X & 0x33333333) + (X >> 2 & 0x33333333);
      X = (X & 0x0F0F0F0F) + (X >> 4 & 0x0F0F0F0F);
      X = (X & 0x00FF00FF) + (X >> 8 & 0x00FF00FF);
      X = (X & 0x0000FFFF) + (X >> 16 & 0x0000FFFF);
      return(X);

butter(稀疏图最短路)

  • floyd改一点过一点数据…查nocow发现需要更高级的算法
  • SPFA 挺好写的…但是注意 farm不是从0开始,建站不一定建在有牛的地方
  • 据说djstra也可以 抄一遍堆的代码..

bitset学习

链接一

//觉得下面几个函数特别有用
.count()
.set()

to_string()
to_long()
//spin
#include<cstdio>
#include<bitset>
#include<iostream>
using namespace std;
int speed[6];
int main()
{
    freopen("spin.in","r",stdin);
    freopen("spin.out","w",stdout);
    bitset <360> now[6],temp[6];
    for(int i=1;i<=5;i++)
    {
        int x;
        cin >> speed[i] >> x;
        for(int j=1;j<=x;j++)
        {
            int start,end;
            cin >> start >> end;
            end += start;
            for(int k=start;k<=end;k++)
                now[i].set(k%360);
        }
    }
    int t=0;
    while(t<360)
    {
        for(int i=0;i<=359;i++)
        {
            int flag=0;
            for(int j=1;j<=5;j++)
                if(!now[j].test(i))
                {
                    flag=1;
                    break;
                }
            if(flag==0)
            {
                cout << t << endl; 
                return 0;
            }
        }
        for(int i=1;i<=5;i++)
        {
            for(int j=0;j<=359;j++)
                temp[i][j]=now[i][(j+360-speed[i])%360];
            now[i]=temp[i];
        }
        t++;
    }
    cout << "none" << endl;
    return 0;
}

你可能感兴趣的:(USACO3.2 还是暴力+bitset学习)