Day1
Calculator
30分暴力
O(2^n) n<=10
另有20分dp等等优化
#include<iostream>
#include<cstdio>
int ans;
int s,t,k;
void readin()
{
scanf("%d%d%d",&s,&t,&k);
}
void dfs(int now,int step)
{
// printf("%d %d\n",now,step);
if(step>k)
//之前读错了题,只要在k步之内都可以统计答案
return;
if(now==t)
ans++;
if(step==k)
//特判一下,如果够步数就不再走
return;
dfs(now+1,step+1);
if(now-1<0)
return;
dfs(now-1,step+1);
}
int main()
{
readin();
if(s>t)
std::swap(s,t);
//虽然似乎30分的数据没卡,但一定要细心,任何情况都要考虑到
dfs(s,0);
printf("%d",ans);
return 0;
}
Work
30分的暴力dp
等等再优化
#include<iostream>
#include<cstdio>
typedef long long ll;
int const maxn=111;
ll pre[maxn],f[maxn];
//第一个点就爆了int
//int极限2147483647,要敏感
int n,k;
void readin()
{
scanf("%d%d",&n,&k);
for(int x,i=1;i<=n;i++)
scanf("%d",&x),pre[i]=pre[i-1]+x;
}
int main()
{
readin();
for(int i=1;i<=n+1;i++)
for(int j=i-1;j>=std::max(0,i-1-k);j--)
//不能让下标为负
//之前边界搞错了,不选i就应该从i的下一个开始再走k个
f[i]=std::max(f[i],f[j]+pre[i-1]-pre[j]);
printf("%lld",f[n+1]);
return 0;
}
Day2
Graph
区区30分暴力dfs竟然调了1h…
耻辱
另有20分暴力dp等等优化
#include<iostream>
#include<cstdio>
#include<cstring>
int const maxn=111,maxm=111,inf=0x1f1f1f1f;
int n,m,s,t;
int cnt;
int head[maxn],vis[maxn];
double maxx=inf;
int mx,mn;
struct E
{
int to,next,w;
E(int to=0,int next=0,int w=0):
to(to),next(next),w(w){}
}e[maxm<<1];
struct node
{
double ans;
int max,min;
node(double ans=0,int max=0,int min=0):
ans(ans),max(max),min(min){}
};
void add(int u,int v,int w)
{
e[++cnt]=(E){v,head[u],w};
head[u]=cnt;
}
int gcd(int a,int b)
{
if(!b)
return a;
return gcd(b,a%b);
}
void readin()
{
scanf("%d%d",&n,&m);
for(int x,y,z,i=1;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
scanf("%d%d",&s,&t);
}
void dfs(int u,int min,int max)
//暴力dfs尽量不加返回值,链上的信息作为参数维护即可
{
if(u==t)
{
double now=(double)max/min;
// double noww=double(max/min);
//注释掉的写法是错的,卵用没有
// printf("%lf %lf\n",now,noww);
if(maxx>now)
{
maxx=now;
mx=max;
mn=min;
}
return;
}
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to,w=e[i].w;
if(vis[v])
continue;
// min=std::min(min,w);
// max=std::max(max,w);
//这地方是令我挂掉的罪魁祸首!!!
//切记:dfs中不要直接改动参数!
// printf("%d %d:%d %d\n",u,v,max,min);
vis[v]=true;
// dfs(v,min,max);
dfs(v,std::min(min,w),std::max(max,w));
vis[v]=false;
}
}
int main()
{
memset(head,-1,sizeof(head));
readin();
vis[s]=true;
dfs(s,inf,0);
if(maxx==inf)
{
puts("IMPOSSIBLE");
return 0;
}
if(!(mx%mn))
{
printf("%.lf",maxx);
return 0;
}
int g=gcd(mn,mx);
printf("%d/%d",mx/g,mn/g);
return 0;
}
Sweet
30分暴力
变量打反,喜闻乐见
若不出岔子,20min还是没问题的
#include<iostream>
#include<cstdio>
#include<cstring>
int const maxn=111,maxm=111,inf=0x1f1f1f1f;
int rans[maxn],op[maxn],bv[maxn],lv[maxn];
int ans=inf;
int n,t;
void read()
{
scanf("%d%d",&n,&t);
for(int i=1;i<=n;i++)
scanf("%d%d",&lv[i],&bv[i]);
}
void dfs(int kind,int step,int mny)
{
if(kind==n)
{
if(step==t)
if(ans>mny)
{
// printf("%d %d\n",ans,mny);
ans=mny;
// for(int i=1;i<=n;i++)
// printf("%d %d\n",rans[i],op[i]);
for(int i=1;i<=n;i++)
rans[i]=op[i];
// puts("\n");
}
return;
}
for(int i=kind+1;i<=n;i++)
{
op[i]=0,dfs(i,step,mny);
op[i]=1,dfs(i,step+1,mny+lv[i]);
op[i]=2,dfs(i,step+2,mny+bv[i]);
}
}
int main()
{
read();
dfs(0,0,0);
printf("%d\n",ans);
for(int i=1;i<=n;i++)
printf("%d\n",rans[i]);
return 0;
}
Day3
Month
#include<iostream>
#include<cstdio>
#include<cmath>
int r[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int nt[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
char s[13];
int isprime(int x)
{
if (!x) return true;
if (x==1) return false;
for (int a=2;a*a<=x;a++)
if (x%a==0) return false;
return true;
}
int if_rain(int year)
{
if(!(year%4))
return true;
if(!(year%400) && !(year%100))
return true;
return false;
}
int calculate(int year,int month,int day)
{
int cnt=0;
int young=std::min(year,1926),old=std::max(year,1926);
if(old==young)
{
if(month>8)
{
for(int i=8;i<=month;i++)
cnt+=nt[i];
cnt+=day;
cnt-=17;
}
if(month<8)
{
for(int i=month;i<=8;i++)
cnt+=nt[i];
cnt+=17;
cnt-=day;
}
if(month==8)
cnt+=abs(17-day);
return cnt;
}
for(int i=young+1;i<=old-1;i++)
{
if(if_rain(i))
cnt+=366;
else
cnt+=365;
}
if(young==year)
{
if(if_rain(year))
{
for(int i=month;i<=12;i++)
cnt+=r[i];
cnt-=day;
}
else
{
for(int i=month;i<=12;i++)
cnt+=nt[i];
cnt-=day;
}
for(int i=1;i<8;i++)
cnt+=nt[i];
cnt+=17;
return cnt;
}
else
{
for(int i=8;i<=12;i++)
cnt+=nt[i];
cnt-=17;
if(if_rain(year))
{
for(int i=1;i<month;i++)
cnt+=r[i];
cnt+=day;
}
else
{
for(int i=1;i<=month;i++)
cnt+=nt[i];
cnt+=day;
}
return cnt;
}
}
int main()
{
// freopen("r.in","r",stdin);
// freopen("r.out","w",stdout);
int n=0;
scanf("%d",&n);
for(int k=1;k<=n;k++)
{
int a,year=0,month=0,day=0;
int j;
scanf("%s",s);
for(j=0;j<4;j++)
year=year*10+s[j]-'0';
for(j=5;j<7;j++)
month=month*10+s[j]-'0';
for(j=8;j<10;j++)
day=day*10+s[j]-'0';
// printf("%d\n",calculate(year,month,day));
// /*
if(year==1926&&month==8&&day==17)
{
printf("Niubi\n");
continue;
}
if(!isprime(calculate(year,month,day)))
{
printf("Niubi\n");
continue;
}
printf("Haixing\n");
// */
}
return 0;
}
改了两天终于改完了…
纯自我差错,未参考题解
技能:
【自食其力】++
【代码能力】++
#include<iostream>
#include<cstdio>
#include<cmath>
int r[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int nt[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
char s[13];
int isprime(int x)
{
if (!x) return true;
if (x==1) return false;
for (int a=2;a*a<=x;a++)
if (x%a==0) return false;
return true;
}
int israin(int year)
{
if(!(year%4) && (year%100))
return true;
if(!(year%400) && !(year%100))
return true;
return false;
}
int calculate(int y_year,int y_month,int y_day)
{
int o_year=1926,o_month=8,o_day=17;
int cnt=0;
if(y_year>o_year)
{
std::swap(y_year,o_year);
std::swap(y_month,o_month);
std::swap(y_day,o_day);
}
// printf("%d %d %d\n",y_year,y_month,y_day);
// printf("%d %d %d\n",o_year,o_month,o_day);
for(int i=y_year;i<=o_year;i++)
{
if(israin(i))
cnt+=366;
else
cnt+=365;
// printf("%d %d\n",i,cnt);
}
if(israin(y_year))
{
for(int i=1;i<=y_month;i++)
cnt-=r[i];
cnt+=r[y_month]-y_day;
}
else
{
for(int i=1;i<=y_month;i++)
cnt-=nt[i];
cnt+=nt[y_month]-y_day;
// printf("%d\n",nt[y_month]-y_day);
}
if(israin(o_year))
for(int i=o_month;i<=12;i++)
cnt-=r[i];
else
for(int i=o_month;i<=12;i++)
cnt-=nt[i];
cnt+=o_day;
return cnt;
}
int main()
{
// freopen("r.in","r",stdin);
// freopen("r.out","w",stdout);
int n=0;
scanf("%d",&n);
for(int k=1;k<=n;k++)
{
int a,year=0,month=0,day=0;
int j;
scanf("%s",s);
for(j=0;j<4;j++)
year=year*10+s[j]-'0';
for(j=5;j<7;j++)
month=month*10+s[j]-'0';
for(j=8;j<10;j++)
day=day*10+s[j]-'0';
// printf("%d\n",calculate(year,month,day));
// /*
if(year==1926&&month==8&&day==17)
{
printf("Niubi\n");
continue;
}
if(isprime(calculate(year,month,day)))
{
printf("Niubi\n");
continue;
}
printf("Haixing\n");
// */
}
return 0;
}
Gay
这道题恶心的一匹,暴力贼难写…
不过也算是知道了next_permutation的强大之处
对于这种枚举情况统计方案数的题,可以用next_permutation打表
#include<iostream>
#include<cstdio>
#include<algorithm>
int const maxn=111,maxm=111,inf=0x1f1f1f1f;
int a[maxn],ans,n;
void read()
{
scanf("%d",&n);
for(int i=1;i<2*n;i++)
a[i]=i;
}
void work()
{
do
{
int flag=false;
for(int i=0;i<2*n&&!flag;i++)
if((a[i]^a[i+1])==1)
flag=true;
if(flag)
continue;
ans++;
}
while(std::next_permutation(a+1,a+2*n));
}
int main()
{
read();
work();
printf("%d",ans);
return 0;
}