版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/oidoidoid/article/details/87014830
A
输出满足条件的三元组的个数
特殊考虑0和1
WA2
细节写的太丑了
#include<iostream>
#include<string.h>
#include<algorithm>
#define N 10005
using namespace std;
long long a[N];
long long sum[200005];
int main(){
int T,ca=0;
scanf("%d",&T);
while (T--){
ca++;
memset(sum,0,sizeof(sum));
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%lld",&a[i]);
sum[a[i]]++;
}
long long ans=0;
sort(a+1,a+1+n);
long long tot1=0,tot0=0;
a[n+1]=2;
for (int i=1;i<=n+1;i++) if (a[i]!=0){ tot0=i-1;break; }
if (tot0>=3) ans+=(tot0*(tot0-1)*(tot0-2)/6);
for (int i=tot0+1;i<=n+1;i++) if (a[i]!=1){ tot1=i-1-tot0;break; }
if (tot1>=3) ans+=(tot1*(tot1-1)*(tot1-2)/6);
for (int i=1;i<=200000;i++){
if (i!=1&&sum[i]>1) ans+=(tot1*sum[i]*(sum[i]-1)/2);
if (tot0>1) ans+=(tot0*(tot0-1)/2*sum[i]);
}
for (int i=tot0+tot1+1;i<=n;i++){
for (int j=i+1;j<=n;j++){
if (a[i]*a[j]<=200000){
ans+=sum[a[i]*a[j]];
}
}
}
printf("Case #%d: %lld\n",ca,ans);
}
return 0;
}
B
似乎是离散化线段树离线回答
懒得套板子了……
C
状压搜索
NM*2^Ct预处理:
1.接下来可达的状态
2.当前状态能量和
3.是否可以直接回到EXIT推出
很妙
最后的搜索没加记忆化会T
#include<iostream>
#include<string.h>
using namespace std;
long long v[105][105],tp[20][2];
int mk[105][105];
long long tot,etot;
long long e[1<<16], nxt[1<<16];
bool ext[1<<16],vis[105][105];
long long f[1<<16];
int ex, ey, sx,sy,n,m;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void pre(int nx, int ny, int now){
for (int i=0;i<4;i++){
int x=nx+dir[i][0];
int y=ny+dir[i][1];
if (x==ex&&y==ey) ext[now]=true;
if (x>0&&x<=n&&y>0&&y<=m&&!vis[x][y]&&v[x][y]!=-100000){
vis[x][y]=true;
if (v[x][y]>=0){
e[now]+=v[x][y];
pre(x,y,now);
}
else{
if (now&(1<<(mk[x][y]-1))){
e[now]+=v[x][y];
pre(x,y,now);
}
else{
nxt[now]|=(1<<(mk[x][y]-1));
}
}
}
}
}
long long dfs(int now){
if (f[now]!=-2) return f[now];
long long res=-1;
if (ext[now]) res=e[now];
for (int i=1;i<=tot;i++){
if( (nxt[now]&(1<<(i-1)))&&v[tp[i][0]][tp[i][1]]+e[now]>=0){
res=max(res,dfs(now|(1<<(i-1))));
}
}
return f[now]=res;
}
int main(){
int T;
scanf("%d",&T);
long long E;
int ca=0;
while (T--){
memset(nxt,0,sizeof(nxt));
memset(ext,0,sizeof(ext));
ca++;
tot=0;
scanf("%d%d%lld%d%d%d%d",&n,&m,&E,&sx,&sy,&ex,&ey);
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
scanf("%lld",&v[i][j]);
if (v[i][j]<0&&v[i][j]!=-100000){
tot++;
mk[i][j]=tot;
tp[tot][0]=i;
tp[tot][1]=j;
}
}
}
for (int i=0;i<=(1<<tot)-1;i++){
e[i]=E;
for (int j=1;j<=n;j++){
for (int k=1;k<=m;k++) vis[j][k]=false;
}
pre(sx,sy,i);
}
for (int i=0;i<=(1<<tot)-1;i++) f[i]=-2;
long long ans=max(-1LL,dfs(0));
printf("Case #%d: %lld\n", ca,ans);
}
}