您的位置:首页 > 其它

USACO 1.5 Binary Numbers

2016-02-18 11:19 337 查看
Notes

把二进制数转化3或4个一组 表示为8(hex 0)或16(octal 0x)进制

bitwise 位运算符

shifting 位移

When shifting to the left, 0’s are inserted in the lower end.

When shifting to the right, the high order bit is duplicated

and inserted for the newly-needed bit (thus preserving the number’s sign).

This means that (-1)>>1 yields -1 instead of 0!

ValueSampleMeaning
x00101100the original x value
x & -x00000100extract 取出 lowest bit set
x | -x11111100create mask for lowest-set-bit & bits to its left
x ^ -x11111000create mask bits to left of lowest bit set
x & (x-1)00101000strip off lowest bit set–> useful to process words in O(bits set)[instead of O(nbits in a word)]
x | (x-1)00101111fill in all bits below lowest bit set
x ^ (x-1)00000111create mask for lowest-set-bit & bits to its right
~x & (x-1)00000011create mask for bits to right of lowest bit set
x | (x+1)00101101toggle lowest zero bit
x / (x&-x)00001011shift number right so lowest set bit is at bit 0

数字三角形

从上向下

sum[i][j]=max(sum[i-1][j],sum[i-1][j-1])+nums[i][j];


从下向上

for (i = 0; i < rows; i++)
res[i] = tri[rows-1][i];
for (i = rows-1; i > 0; i--)
for (j = 0; j <= i; j++)
res[j] = tri[i-1][j] + max(res[j],res[j+1]);


pprimes*

本来想筛法暴力的..居然会超内存..打表算了= =

(希望打表不要被封号…

官方题解

Since there are only about 10,000 palindromes less than 100,000,000, we can just test each one to see if it is prime and in the range.(hint:回文数太少了,枚举回文数)

To generate a palindrome, we start with the first half and reverse it. The trick is that we can repeat the middle character or not repeat the middle character.(枚举一半即可)

The problem can be simplified slightly by noticing that any even palindrome is divisible by 11. Therefore, 11 is the ONLY even prime palindrome. This eliminates the need to deal with 2 cases(优化复杂度,任何偶数回文能被11整除)

整数的奇数位数字的和与偶数位数字的和之差,如果是11的倍数这数就是11的倍数,否则不是。

//枚举不同长度的
void generate(void){
genoddeven(1, 9);
genoddeven(10, 99);
genoddeven(100, 999);
genoddeven(1000, 9999);
}
/*
BTW 枚举量小的时候不用for循环结构会好看一些
*/
void genoddeven(int lo, int hi){
int i;
//奇数枚举
for(i=lo; i<=hi; i++)
gen(i, 1);
//偶数枚举
for(i=lo; i<=hi; i++)
gen(i, 0);
}
void gen(int i, int isodd){
char buf[30];
char *p, *q;
long n;
//这里的枚举甚是奇妙
//sprintf应该算是很快的tos()

sprintf(buf, "%d", i);
//p是最后一位+1
p = buf+strlen(buf);
/* 奇数: q 最后一位   的指针
偶数: q 倒数第二位 的指针*/
q = p - isodd;

//q没有枚举到第一位时,p往后走,等于前面对称位置

while(q > buf)
*p++ = *--q;

*p = '\0';

//说好的没有toi函数呢= =
n = atol(buf);
if(a <= n && n <= b && isprime(n))
fprintf(fout, "%ld\n", n);
}


//另一种生成回文数的方法.更加直接  </
int reverse2(int num, int middle) {
int i, save=num, digit, combino = 1;
for (i = 0; num; num /= 10) {
digit = num % 10;
i = 10 * i + digit;
combino *= 10;
}
return i+10*combino*save+combino*middle;
}


//又一村(原代码简化版

void genPalind(int num, int add, int mulleft, int mulright){

/*
expects 4 parameters
num     = 1,3,5,7   剩下需要生成的回文数长度
add     = 0         左右已经定型数字 如10001
mulleft = 10^(n-1)  左右间隔倍数(左数位)
mulright= 1         左右间隔倍数(右数位)

int main()
genPalind(3, 0, 100, 1);
genPalind(5, 0, 10000, 1);
genPalind(7, 0, 1000000, 1);
void tryPalind(int)
判断是否是在[a,b]内的素数
*/
int i; //生成数

if (num==2){
for (i=0; i<10; i++)
tryPalind(add+mulleft*i+mulright*i);
}
else if (num==1){
for (i=0; i<10; i++)
tryPalind(add+mulright*i);
}
else {
//尝试少两位的回文数?
for (i=0; i<10; i++)
genPalind(num-2, add+i*mulleft+i*mulright, mulleft/10, nmulright*10);
}

}


从左到右任何分割素数

recursive search

void dfs(int now,int num){
if (num==n)
if (isprime(now))
fout<<now<<endl;
else if(isprime(now))
for (int i=1; i<10; i+=2)
dfs(now*10+i, num+1);

}


还是很好奇csdn的markdown编辑器应该如何愉快地玩耍
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: