分数
60(100)+32(32)+0(0)+25(30)=117(162)
题目
T1: 【NOIP2020】water
这是一个比较明显的拓扑,直接bfs或dfs模拟即可。
60是没打高精度,NOIP不给用__int128。
但我改题不想打就打了__int128.
代码
#include<cstdio>
#define Fu(i,a,b) for(register int i=(a);i<=(b);i++)
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define LL __int128
LL z[100005],m[100005];
int n,s,d[100005][10],vis[100005];
bool bj=true;
LL gcd(LL a,LL b){
LL r=a%b;
while(r!=0) a=b,b=r,r=a%b;
return b;
}
void add(LL &a,LL &b,LL a1,LL b1){
LL r=gcd(b*b1,a*b1+a1*b);
a=(a*b1+a1*b)/r,b=b*b1/r;
}
inline void print(LL x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9) print(x/10);
putchar(x%10+'0');
}
int main(){
// fre(water);
scanf("%d%d",&n,&s);
Fu(i,1,n){
scanf("%d",&d[i][0]);
Fu(j,1,d[i][0]){
scanf("%d",&d[i][j]);
vis[d[i][j]]++;
}
}
Fu(i,1,n){
if(vis[i]==0) z[i]=1;
m[i]=1;
}
while(bj){
bj=false;
Fu(i,1,n){
if(d[i][0]!=0&&z[i]!=0){
Fu(j,1,d[i][0]){
add(z[d[i][j]],m[d[i][j]],z[i],m[i]*d[i][0]);
}
z[i]=0,m[i]=1;
}
}
Fu(i,1,n)if(d[i][0]!=0&&z[i]!=0){
bj=true;
break;
}
}
Fu(i,1,n) if(d[i][0]==0){
print(z[i]);
printf(" ");
print(m[i]);
printf("\n");
}
return 0;
}
T2: 【NOIP2020】string
不会正解,就打了一个暴力,结果…
代码:
#include<cstdio>
#include<cmath>
#define Fu(i,a,b) for(register int i=(a);i<=(b);i++)
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
using namespace std;
int t,n,ans;
char a[1048580];
int find(int l,int r){
int u[35],tot=0;
Fu(i,1,30) u[i]=0;
Fu(i,l,r) u[a[i]-'a'+1]++;
Fu(i,1,30) if(u[i]%2==1) tot++;
return tot;
}
int num(int i,int j){
int tot=0;
bool bj=true;
Fu(l,1,j){
Fu(k,1,i/j-1){
if(a[(k-1)*j+l]!=a[k*j+l]){
bj=false;
break;
}
}
if(!bj)break;
}
if(bj){
Fu(k,1,j-1){
if(find(1,k)<=find(i+1,n)){
tot++;
}
}
}
return tot;
}
int main(){
// fre(string);
scanf("%d",&t);
Fu(o,1,t){
n=0,ans=0;
a[++n]=getchar();
while(a[n]<'a'||a[n]>'z')a[n]=getchar();
while(a[n]>='a'&&a[n]<='z')a[++n]=getchar();n--;
Fu(i,2,n-1){
Fu(j,1,sqrt(i)){
if(i%j==0){
if(j!=i/j) ans+=num(i,j)+num(i,i/j);
else ans+=num(i,j);
}
}
}
printf("%d\n",ans);
}
return 0;
}
T3: 【NOIP2020】ball
无
T4: 【NOIP2020】walk
根据题意模拟就能30分,但我没有特判-1的情况,白掉5分。
代码
#include<cstdio>
#define Fu(i,a,b) for(register int i=(a);i<=(b);i++)
#define Fd(i,a,b) for(register int i=(a);i>=(b);i--)
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
int n,k,a[15],w[15],b[15],tot;
int way[100005][2];
void dfs(int o){
if(o>k){
int c[15],ans=0;
Fu(i,1,k)c[i]=b[i];
bool bz=true;
while(bz){
Fu(i,1,n){
c[way[i][0]]+=way[i][1];
tot++;
if(c[way[i][0]]>w[way[i][0]]||c[way[i][0]]<1){
bz=false;
break;
}
}
}
return ;
}
Fu(i,1,w[o]){
b[o]=i;
dfs(o+1);
}
}
int main(){
// fre(walk);
scanf("%d%d",&n,&k);
Fu(i,1,k) scanf("%d",&w[i]);
Fu(i,1,n){
scanf("%d%d",&way[i][0],&way[i][1]);
a[way[i][0]]+=way[i][1];
}
int bj=0;
Fu(i,1,k) if(a[i]!=0) bj=1;
if(bj==0){
printf("-1");
return 0;
}
dfs(1);
printf("%d",tot);
return 0;
}