1270 Unique Digit Number
这道题是数位dp。
#include<stdio.h>
__int64 a[9000000];
int t[9000000]; //不看t的值,t用来标记,记录独特数占了哪些位 也就是用了哪个数
int main()
{
int i,j;
int num=1;
for(i= 1;i<10;i++)
{
a[num] = i;
t[num] =t[num]|(1<<i);
num++;
}
for(i=1;i<num;i++)//num==10
{
for(j=0;j<10;j++)
{
if((1<<j) & ~t[i])//~是按位取反.
{
a[num]=a[i]*10+j;
t[num]=t[i]|(1<<j);
num++;
}
}
}
while(scanf("%d",&i)!=EOF)
printf("%I64d\n",a[i-1]);
}
1386 彩球
题意:有n个气球,n<10^4,每个气球颜色为ci,ci<10的7次方,问选3种不同颜色的气球有多少种方案数
思路:
想用DP,没写出来。
想直接统计,T了。
这是高中数学题? 不能直接统计,直接统计会超时,得用间接法。
用Hash统计每种颜色个数,所有的方案是(n,3)
减去三色相同和两色相同的方案数即可。
代码:
#include<stdio.h>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
#define Debug(x) cout<<#x<<':'<<x<<endl
typedef __int64 ll;
#define INF 0x7fffffff//10^9级别,不到2^32
#define mo 20011
#define maxn 10000
inline ll read() {
char c = getchar(); ll x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
ll re[mo+11];
inline ll hash1(ll n){
ll x=n%mo;
if(re[x]==INF) {re[x]=n;return x;}
else{
ll i=0;
while(re[(x+i)%mo]!=INF){
if(re[(x+i)%mo]!=n) i++;
else return (x+i)%mo;
}
re[(x+i)%mo]=n;
return (x+i)%mo;
}
}
void init(){//哈希表初始化
for(ll i=0;i<mo;i++) re[i]=INF;
}
int main(){
ll t;
t=read();
while(t--){
init();
ll co[mo+11]={0};
ll ar[mo+11]={0};
ll n;
n=read();
for(ll i=1;i<=n;i++){
ll t;t=read();
co[hash1(t)]++;
}
ll step=0;
for(ll i=0;i<mo;i++){
if(co[i]!=0){
ar[++step]=co[i];
}
}
ll ans=n*(n-1)*(n-2)/6;
for(ll i=1;i<=step;i++){
if(ar[i]>=3) ans=ans-ar[i]*(ar[i]-1)*(ar[i]-2)/6;
if(ar[i]>=2) ans=ans-ar[i]*(ar[i]-1)/2*(n-ar[i]);
}
printf("%I64d\n",ans);
}
return 0;
}