題目
3811,3812,3813
失分小結
估分
100+(15+)+?≈130
(第三題最後幾分鐘亂搞的dfs)
實際分數
100+10+35=145
第二題炸了…還有第三題其他同學dfs都有P50.
題解
解析參考LOJ.
T1
P100
簡單哈希.
CODE
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define N 5000005
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
#define ROF(i,a,b) for(int i=(a),i##_END_=(b);i>=i##_END_;i--)
char A[N];
int che[N];
int k,MAX=0;
int ha[1500000];
inline void Max(int &x,int y){if(x<y)x=y;}
int main() {
scanf("%s",A+1);
int n=strlen(A+1);
FOR(i,1,n) { //A:1,C:2,T:3,G:0
if(A[i]=='A')che[i]=1;
else if(A[i]=='C')che[i]=2;
else if(A[i]=='T')che[i]=3;
else che[i]=0;
}
scanf("%d",&k);
FOR(i,1,n-k+1) {
int t=0;
FOR(j,i,i+k-1)t=t*4+che[j];
ha[t]++;
Max(MAX,ha[t]);
}
printf("%d\n",MAX);
return 0;
}
T2
P15
CODE
#include<cstdio>
#include<iostream>
using namespace std;
template <class T>void Rd(T &x) {
x=0;
char c,f=1;
while(c=getchar(),c<48)if(c=='-')f=-1;
do x=(x<<1)+(x<<3)+(c^48);
while(c=getchar(),c>=48);
x*=f;
}
#define M 300005
int n,m,S[M];
struct node {
int a0,a1,k;
} Q[M];
long long A[105];
int main() {
Rd(m);
for(int i=1; i<=m; ++i)Rd(S[i]);
Rd(n);
for(int i=1; i<=n; ++i)Rd(Q[i].a0),Rd(Q[i].a1),Rd(Q[i].k);
for(int i=1; i<=n; ++i) {
A[0]=Q[i].a0;
A[1]=Q[i].a1;
for(int j=2; j<=S[m]; ++j)A[j]=Q[i].k*A[j-1]+A[j-2];
int p1=-1,p2=-1;
for(int j=1; j<=m; ++j) {
long long x=A[S[j]];
if(p1==-1||A[S[p1]]<x)p1=j;
if(p2==-1||A[S[p2]]>x)p2=j;
}
printf("%d %d\n",S[p1],S[p2]);
}
return 0;
}
P100
CODE
#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
template<typename T>inline void rd(T &x) {
x=0;char c,f=1;
while(c=getchar(),c<48)if(c=='-')f=-1;
do x=(x<<3)+(x<<1)+(c&15);
while(c=getchar(),c>47);
x*=f;
}
int S[300005];
ll A[300005];
int main() {
int n,m,k;
rd(m);
for(int i=1; i<=m; i++)rd(S[i]);
rd(n);
while(n--) {
rd(A[0]),rd(A[1]),rd(k);
if(!A[0]&&!A[1]) {
printf("%d %d\n",S[1],S[1]);
continue;
}
int las=0;
int MAXi=S[1],MINi=S[1];
for(int i=2; i<=S[m]; i++) {
A[i]=A[i-1]*k+A[i-2];
if((A[i]<0&&A[i-1]<0)||(A[i]>=0&&A[i-1]>=0)) {
if(A[i]>0&&max(A[i],A[i-1])>max(A[0],A[1])) {
las=i;
break;
}
if(A[i]<0&&min(A[i],A[i-1])<min(A[0],A[1])) {
las=i;
break;
}
}
}
if(!las)las=S[m];
for(int j=2; j<=m; j++) {
if(S[j]>las)break;
if(A[S[j]]>A[MAXi])MAXi=S[j];
if(A[S[j]]<A[MINi])MINi=S[j];
}
if(las<S[m]) {
if(A[las]>0)MAXi=S[m];
if(A[las]<0)MINi=S[m];
}
printf("%d %d\n",MAXi,MINi);
}
return 0;
}
T3
P35
dfs.
CODE
#include<cstdio>
#include<cstdlib>
#include<memory.h>
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
#define ROF(i,a,b) for(int i=(a),i##_END_=(b);i>=i##_END_;i--)
#define N 105
#define M 1005
int n,m,C,T,ans;
int p[N],c[N];
int dis[N][N];
template<typename T>inline bool Max(T&x,T y) {if(x<y)x=y;return x==y;}
template<typename T>inline bool Min(T&x,T y) {if(x>y)x=y;return x==y;}
void dfs(int x,int cc,int mon,int len){
if(len==0){Max(ans,mon);return;}
if(mon<=ans)return;
if(cc)for(int i=1;i<=n;i++)
if(len-dis[x][i]>=0)
dfs(i,cc-1,mon,len-dis[x][i]);
if(cc<c[x]&&mon>=p[x])
dfs(x,c[x],mon-p[x],len);
}
int main(){
// freopen("trip.in","r",stdin);
// freopen("trip.out","w",stdout);
scanf("%d %d %d %d",&n,&m,&C,&T);
for(int i=1;i<=n;i++){
scanf("%d %d",&p[i],&c[i]);
Min(c[i],C);
}
memset(dis,63,sizeof dis);
int a,b,l;
for(int i=1;i<=m;i++){
scanf("%d %d %d",&a,&b,&l);
Min(dis[a][b],l);
}
while(T--){
ans=-1;
int st,len,money;
scanf("%d %d %d",&st,&money,&len);
dfs(st,0,money,len);
printf("%d\n",ans);
}
return 0;
}
P50
記憶化搜索.
CODE
#include<bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a),i_##end_=(b);i<=i_##end_;i++)
#define DFOR(i,a,b) for(int i=(a),i_##end_=(b);i>=i_##end_;i--)
#define INF 0x3f3f3f3f
#define M 105
template<typename T>void rd(T &x) {
x=0;char c,f=1;
while(c=getchar(),c<48)if(c=='-')f=-1;
do x=(x<<1)+(x<<3)+(c&15);
while(c=getchar(),c>47);
x*=f;
}
template<typename T,typename _>void Max(T&a,_ b) {if(a<b)a=b;}
template<typename T,typename _>void Min(T&a,_ b) {if(a>b)a=b;}
int n,m,C,T,S,Q,D;
int Head[M],Cost[1001<<1],To[1001<<1],Nxt[1001<<1],Tot;
void Add_Edge(int a,int b,int c) {
Nxt[++Tot]=Head[a];
Head[a]=Tot;
To[Tot]=b;
Cost[Tot]=c;
}
struct Node {int Pr,c;} A[M];
int DP[105][1005][305];
int Dfs(int x,int cc,int len) {
if(~DP[x][len][cc]) return DP[x][len][cc];
if(len<=0) return DP[x][len][cc]=0;
DP[x][len][cc]=INF;
for(int i=Head[x];i;i=Nxt[i]) {
int to=To[i],Tmp;
if(cc!=0) {
Tmp=Dfs(to,cc-1,len-Cost[i]);
Min(DP[x][len][cc],Tmp);
}
if(cc<min(C,A[x].c) ) {
Tmp=Dfs(to,min(C,A[x].c)-1,len-Cost[i])+A[x].Pr;
Min(DP[x][len][cc],Tmp);
}
}
return DP[x][len][cc];
}
int main() {
rd(n),rd(m),rd(C),rd(T);
FOR(i,1,n) rd(A[i].Pr),rd(A[i].c);
FOR(i,1,m) {
int a,b,c;
rd(a),rd(b),rd(c);
Add_Edge(a,b,c);
}
while(T--) {
rd(S),rd(Q),rd(D);
memset(DP,-1,sizeof DP);
int Tmp=Dfs(S,0,D);
if(Tmp>Q) puts("-1");
else printf("%d\n",Q-Tmp);
}
return 0;
}
P100
CODE
#include <cstdio>
#define ll long long
#define INF -(1ll<<61)
int n,m,C,T,p[110],c[110];
ll f[110][10010],dis[20][110][110],A[110],B[110],D[110][110];
template<typename T,typename _>inline void Max(T &x,_ y){if(x<y)x=y;}
template<typename T,typename _>inline void Min(T &x,_ y){if(x>y)x=y;}
int main() {
scanf("%d%d%d%d",&n,&m,&C,&T);
for(int i=0; i<n; i++) {
scanf("%d%d",&p[i],&c[i]);
Min(c[i],C);
for(int j=0; j<n; j++)dis[0][i][j]=INF;
dis[0][i][i]=0;
}
for(int i=0; i<m; i++) {
int a,b,l;
scanf("%d%d%d",&a,&b,&l);
Max(dis[0][a-1][b-1],l);
}
for(int k=1; k<17; k++)
for(int i=0; i<n; i++)
for(int j=0; j<n; j++) {
dis[k][i][j]=INF;
for(int l=0; l<n; l++)
Max(dis[k][i][j],dis[k-1][i][l]+dis[k-1][l][j]);
}
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++)A[j]=(j==i)?0:INF;
for(int k=16; k>=0; k--)
if(c[i]>>k&1) {
for(int j=0; j<n; j++) {
B[j]=INF;
for(int l=0; l<n; l++)
Max(B[j],A[l]+dis[k][l][j]);
}
for(int j=0; j<n; j++)A[j]=B[j];
}
for(int j=0; j<n; j++)D[i][j]=A[j];
}
for(int j=0; j<=n*n; j++)
for(int i=0; i<n; i++)
if(j>=p[i])
for(int k=0; k<n; k++)
Max(f[i][j],f[k][j-p[i]]+D[i][k]);
while(T--) {
int s,q,d,ans=1;
scanf("%d%d%d",&s,&q,&d);
--s;
while(ans<=q&&f[s][ans]<d)ans++;
printf("%d\n",ans>q?-1:q-ans);
}
return 0;
}