题目:http://poj.org/problem?id=3292
AC代码(C++):
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>
#define INF 0xfffffff
#define MAXN 100105
using namespace std;
int Hsp[250010];
int cnt[250010];
void table(){
memset(Hsp,0,sizeof(Hsp));
for(int i = 2; i <= 250009; i++){
for(int j = 2; j <= i; j++){
if(4*i*j-3*i-3*j+3>250009)break;
if(Hsp[i]==0&&Hsp[j]==0)Hsp[4*i*j-3*i-3*j+3]=1;
else Hsp[4*i*j-3*i-3*j+3]=2;
}
}
cnt[1] = 0;
for(int i = 2; i < 250010; i++){
if(Hsp[i]==1)cnt[i]=cnt[i-1]+1;
else cnt[i] = cnt[i-1];
}
}
int main(){
table();
int n;
while(cin>>n){
if(n==0)break;
cout<<n<<' '<<cnt[(n+3)/4]<<endl;
}
}
总结: 打表. H-num分三种: Hp, Hsp, Hc. 打表从小往大打, 第一次遇到的数都是Hp, 故首先全部置0, 代表是Hp. 然后两个两个数取出来, 如果两个都是Hp则乘积是Hsp, 标记为1, 否则就是Hc, 标记为2.