Day1
早上8:00上课
7:40还在家里的我(颓
匆匆忙忙地到了学校(本校)
去了趟宿舍放东西
8:10左右到了教室
迟到了一小会没有听到wbs老师的自我介绍
感觉他好可爱
我以为我是最迟的......没想到hyc大佬更迟......
第一天就上数论感觉要被劝退回隔壁pj组了
各种奇怪的定理wbs老师说只是简单的复习罢了......然而蒟蒻我脑子要炸了......
大概讲了扩欧 中国剩余定理 分块优化 欧拉函数 莫比乌斯函数 积性函数啥的
然后就没听懂几个
感觉被吊打......
中午12:00
宿舍吃鸡
前两天都好迟睡中午又没睡 感觉眼睛超级酸
下午考试毫无状态
T1:
用数论推一推
大概是用分块写吧
考试代码(90分):
#include <iostream> #include<cstdio> using namespace std; long long n,k,ans,r,t; int main() { freopen("sum.in","r",stdin); freopen("sum.out","w",stdout); cin>>n>>k; for(long long l=1;l<=n;l=r+1) { r=(t=k/l)?(k/t):n; ans-=t*(r-l+1)*(l+r)>>1; } cout<<ans+n*k; fclose(stdin); fclose(stdout); }
正解:
忘记加一个取最小值然后超限了
#include <iostream> #include<cstdio> using namespace std; long long n,k,ans,r,t; int main() { cin>>n>>k; for(long long l=1;l<=n;l=r+1) { r=(t=k/l)?min((k/t),n):n;//取最小 ans-=t*(r-l+1)*(l+r)>>1; } cout<<ans+n*k; }
T2:
当P是质数的时候裸扩欧
不是的时候就不会了......
考试的时候就打了扩欧骗骗分
扩欧证明:https://www.cnblogs.com/BrokenString/p/9275595.html
考试代码(0分):
#include<iostream> #include<cstdio> using namespace std; void exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return; } exgcd(b,a%b,y,x); y-=a/b*x; } int main() { freopen("equation.in","r",stdin); freopen("equation.out","w",stdout); int t; cin>>t; for(int i=1;i<=t;i++) { int x,y,a,b,c; cin>>a>>c>>b; exgcd(a,b,x,y); cout<<x; } fclose(stdin); fclose(stdout); }
正解:
看不懂
大概是Ax+Cy=B
然后B是gcd(A,C)的倍数推一下用扩欧
#include<cstdio> #include<algorithm> #include<cmath> #include<map> using namespace std; typedef long long ll; int gcd(int a,int b){ if(a<b) swap(a,b); while(b) swap(a%=b,b); return a; } void exgcd(int a,int b,ll &x,ll &y){ if(!b){x=1,y=0;return;} ll p,q;exgcd(b,a%b,p,q); x=q,y=p-a/b*q; } int solve(int a,int b,int p){ a%=p,b%=p; if(!a){ if(b) return -1; return 0; } int d=gcd(a,p);ll x,y; if(b%d) return -1; exgcd(p,a,x,y); int g=y%p*(b/d)%p; return g<0?g+p:g; } int main(){ freopen("equation.in","r",stdin); freopen("equation.out","w",stdout); int T,a,p,b; for(scanf("%d",&T);T--;){ scanf("%d%d%d",&a,&b,&p); a%=p,b%=p; int x=solve(a,b,p); if(x==-1) puts("No Solution"); else printf("%d ",x); } return 0; }
T3:
这是什么鬼 完全没思路
然后打了个随机输出十以内的数骗分
考试代码(0分):
#include<iostream> #include<cstdlib> #include<ctime> #include<cstdio> using namespace std; int main() { freopen("gcd.in","r",stdin); freopen("gcd.out","w",stdout); srand((unsigned)time(NULL)); cout<<rand()%10<<' '; fclose(stdin); fclose(stdout); }
正解:
每次取最小值乘上另一个值后加入这个值
把另外两个数删掉
#include<stdio.h> int n,t,p[1250],res,tmp; bool v[10001]; int main() { freopen("gcd.in","r",stdin); freopen("gcd.out","w",stdout); scanf("%d",&n); for(int i=2;i<=n;++i) if(!v[i]){ p[++t]=i; for(int j=i;j<=n;j+=i) v[j]=1; } for(int l=1,r=t;l<=r;--r){ tmp=p[r]; while(l<=r&&tmp*p[l]<=n) tmp*=p[l++]; ++res; } printf("%d",res); }
晚上6:00开始晚自习
晚上就做了一道扩欧的模板题 写了一下题解啥的
然后wbs老师走了以后就开始和hyc大佬悄咪咪的吃鸡
回宿舍后看了蜘蛛侠3就24:00了
补觉zzz......
Day2
早上7:40多起床
匆忙啃了几口面包就跑到机房去了
早上上了贪心 分治 树状数组 Huffman编码 KMP 还有一堆完全听不懂的高数和概率期望
一早上听不懂强行理解下来感觉脑子要bang
中午偷偷吃泡面看钢铁侠3半小时
T1:
考试的时候到是想到了
每次取2个最小值加起来的值放回原集合中
30分钟打完
考试代码(100分):
#include<iostream> #include<cstdio> #include <queue> using namespace std; priority_queue<int, vector<int>, greater<int> > H; long long n,ans; long long len[200005]; int main() { freopen("cut.in","r",stdin); freopen("cut.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) { cin>>len[i]; H.push(len[i]); } while(H.size()>1) { int k=0; k+=H.top(); H.pop(); k+=H.top(); H.pop(); ans+=k; if(H.empty()) break; H.push(k); } cout<<ans; fclose(stdin); fclose(stdout); }
T2:
树状数组并不会
乱搞20分
考试代码(20分):
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; int a[10010]; int dp[10010]; int main() { freopen("choose.in","r",stdin); freopen("choose.out","w",stdout); int n,m; cin>>n>>m; for(int i=0;i<n;i++) { scanf("%d",&a[i]); dp[i]=1; } int ans=0; for(int i=1;i<n;i++) { for(int j=0;j<i;j++) { if(a[j]<a[i]) { dp[i]=max(dp[j]+1,dp[i]); } } ans=max(ans,dp[i]); } int k=n-ans; if(k>=m) printf("%d",ans); else { ans-=m-k; printf("%d",ans); } fclose(stdin); fclose(stdout); }
正解:
#include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=100002; inline int get(){ char ch;while(!isdigit(ch=getchar())); int x=ch-48; while(isdigit(ch=getchar())) x=(x<<3)+(x<<1)+ch-48; return x; } int n,m,ta[N],a[N],f1[N],f2[N],bit[N]; int main(){ freopen("choose.in","r",stdin); freopen("choose.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) ta[i]=a[i]=get(); sort(ta+1,ta+n+1); int l=unique(ta+1,ta+n+1)-ta-1; for(int i=1;i<=n;++i) a[i]=lower_bound(ta+1,ta+l+1,a[i])-ta; for(int i=1;i<=n;++i){ int ret=0; for(int j=a[i]-1;j;j-=j&-j) ret=max(ret,bit[j]); f1[i]=ret+1; for(int j=a[i];j<=l;j+=j&-j) bit[j]=max(bit[j],f1[i]); } memset(bit+1,0,l<<2); for(int i=n;i;--i){ int ret=0; for(int j=a[i]+1;j<=l;j+=j&-j) ret=max(ret,bit[j]); f2[i]=ret+1; for(int j=a[i];j;j-=j&-j) bit[j]=max(bit[j],f2[i]); } memset(bit+1,0,l<<2); int ans=0,len=n-m+1; f1[0]=f2[n+1]=0,a[n+1]=l+1; for(int i=1;i<=len;++i){ int ret=0; for(int j=a[i+m]-1;j;j-=j&-j) ret=max(ret,bit[j]); ans=max(ans,ret+f2[i+m]); for(int j=a[i];j<=l;j+=j&-j) bit[j]=max(bit[j],f1[i]); } printf("%d ",ans); return 0; }
T3:
KMP题
并不会
直接放弃
考试代码(0分):
#include<iostream> #include<cstdio> #include<string> using namespace std; int main() { while(~scanf("%s",a)) { string a; string b; cin>>a; b[0]=a[0]; for(int i=1;i<a.size();i++) { b[i]=a[i]; while(a[i]==a[1]) { } if(b.size()==a.size()) { cout<<1<<endl; break; } } } }
正解:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 1000005; int next[maxn]; void get(char *s) { int l=strlen(s); int j=0,k=-1; next[0]=-1; while(j<l) { if(k == -1 || s[j] == s[k]) { next[++j]=++k; } else { k = next[k]; } } } char s[maxn]; int main() { freopen("string.in","r",stdin); freopen("string.out","w",stdout); while(~scanf("%s",s) ) { get(s); int ans=1; int l=strlen(s); if(l%(l-next[l])==0) { ans=l/(l-next[l]); } printf("%d ",ans); } }
晚上
敲了一下KMP的板子
还有树状数组1 2的板子
晚上看了一部钢铁侠3
呼哧呼哧睡觉~
Day3
早上8:00到机房
发现机房只有我们学校的人了???
原来其他学校的人都被劝退到隔壁PJ了???
好吧我承认有的我也听不懂
早上上了一堆的暴搜
还有DFS序 迭代加深 A* 一些物理题???
看了几道题目贼长的暴搜感觉脑子炸once again
中午12:00
在食堂吃饭下大雨被困住
三个瓜皮跑到旁边宿舍躲雨吃鸡
下午考试
T1:
被wbs老师耍了一波......
说好的题目不用树状数组的咧?
然后啪啦啪啦打了2h
还TM多打了测试时用的序列(我好菜啊
考试代码(0分):
#include<iostream> #include<cstdio> using namespace std; int n,m; struct edge { int pre; int next; int to; }e[100010]; int f[100010]; int ans[100010]; int xu[100010]; int head[100010]; int sum; void add(int x,int y) { e[++m].pre=x; e[m].to=y; e[m].next=head[x]; head[x]=m; } void dfs(int x) { xu[++sum]=x; int u=head[x]; if(u==0) return; while(u!=0) { dfs(e[u].to); f[x]+=f[e[u].to]+1; u=e[u].next; } } int main() { freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); cin>>n; for(int i=2;i<=n;i++) { int x; cin>>x; add(x,i); } dfs(1); for(int i=1;i<=n;i++) cout<<xu[i]<<" "; cout<<endl;//多输出这行少了30分 for(int i=1;i<=n;i++) { for(int j=i+1;j<=i+f[xu[i]];j++) { if(xu[j]<xu[i]) ans[xu[i]]++; } } for(int i=1;i<=n;i++) cout<<ans[i]<<" "; fclose(stdin); fclose(stdout); }
正解:
要用树状数组啥的
没弄出来
T2:
早上上的例题然而并不会
埃及分数迭代加深
考试时放弃(0分)
正解:
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #define N 1000 using namespace std; long long ans[N],s[N],mo,ch; int dep; long long gcd(long long a,long long b){return b==0?a:gcd(b,a%b);} void outp() { int i; if (ans[dep]>s[dep]) { for (i=1;i<=dep;i++) { ans[i]=s[i]; } } } void dfs(long long x,long long y,int d) { long long a,b,i,w; if (d==dep) { s[d]=y; if ((x==1)&&(s[d]>s[d-1])) outp(); return; } for (i=max(s[d-1]+1,y/x+1);i<(dep-d+1)*y/x;i++) { b=y*i/gcd(y,i); a=b/y*x-b/i; w=gcd(a,b); a/=w; b/=w; s[d]=i; dfs(a,b,d+1); } } int main() { int i=0,j; scanf("%lld%lld",&ch,&mo); i=gcd(ch,mo); ch/=i; mo/=i; for (dep=2;;dep++) { ans[1]=0; s[0]=0; ans[dep]=2000000000; dfs(ch,mo,1); if (ans[1]!=0) break; } for (j=1;j<=dep;j++) { printf("%lld ",ans[j]); } printf(" "); return 0; }
T3:
一道闲得蛋疼的物理题......
前70分暴力求公式
后三十分用调和函数大数公式
由于边加边乘少了30
考试代码(40分):
#include<iostream> #include<cmath> #include<cstdio> using namespace std; double n,l,ans; int main() { freopen("book.in","r",stdin); freopen("book.out","w",stdout); cin>>n>>l; for(double i=1;i<=n;i++) { ans+=1/(2*i)*l; } printf("%.4f",ans); fclose(stdin); fclose(stdout); }
正解:
没写......
晚上晚自习
wbs老师说他要回厦大上课了
苦逼......
明天来上课的是他的学长gtc
他说我们不要再迟到了
不给他面子也要给gtc面子
害怕......
晚上看美国队长3
Day4
早上上计算几何
大多都是高中数学
划了一早上的水......
早上的课已经听过三遍了
然而代码还是不会写
中午日常吃鸡
听说下午gtc老师要给我们信心
出得简单点
T1:
判读两条直线是否有交点
裸裸地套公式(然而蒟蒻写的太长看错了
考试代码(10分):
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int n,ans; float p[101][3][3]; void cross(int i,int j) { if(((p[j][1][1]-p[i][1][1])*(p[i][2][2]-p[i][1][2])-(p[i][2][1]-p[i][1][1])*(p[j][1][2]-p[i][1][2]))*((p[i][2][1]-p[i][1][1])*(p[j][2][2]-p[i][1][2])-(p[i][2][1]-p[i][1][1])*(p[j][2][2]-p[i][1][2]))>=0) if(((p[i][1][1]-p[j][2][1])*(p[j][1][2]-p[j][2][2])-(p[j][1][1]-p[j][2][1])*(p[i][1][2]-p[j][2][2]))*((p[j][1][1]-p[j][2][1])*(p[i][2][2]-p[j][2][2])-(p[i][2][1]-p[j][2][1])*(p[j][1][2]-p[j][2][2]))>=0) ans++; return; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) { cin>>p[i][1][1]>>p[i][1][2]>>p[i][2][1]>>p[i][2][2]; for(int j=1;j<i;j++) cross(i,j); } cout<<ans; fclose(stdin); fclose(stdout); }
正解:
有一个点卡精度
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int n,ans; double p[101][3][3]; int t(double a) { if (fabs(a) < 1e-5) return 0; return a > 1e-5 ? 1 : -1;//因为只要判断符号所以1或-1即可 } void cross(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4) { if(t((x3-x1)*(y2-y1)-(x2-x1)*(y3-y1))*t((x2-x1)*(y4-y1)-(x4-x1)*(y2-y1))>=0) if(t((x1-x4)*(y3-y4)-(x3-x4)*(y1-y4))*t((x3-x4)*(y2-y4)-(x2-x4)*(y3-y4))>=0) ans++; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) { cin>>p[i][1][1]>>p[i][1][2]>>p[i][2][1]>>p[i][2][2]; for(int j=1;j<i;j++) cross(p[j][1][1],p[j][1][2],p[j][2][1],p[j][2][2],p[i][1][1],p[i][1][2],p[i][2][1],p[i][2][2]); } cout<<ans; fclose(stdin); fclose(stdout); }
T2:
判断点到线的距离
暴力写了部分分
考试代码(40分):
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int n,r,ans; float p[50050][3]; int pd(int x,int y) { float x1=p[x][1]; float y1=p[x][2]; float x2=p[y][1]; float y2=p[y][2]; return (0-x1)*(x2-x1)+(0-y1)*(y2-y1); } float cross(float x1,float y1,float x2,float y2) { float d=x1*y2-x2*y1; if(d>=0) return d; return -d; } float dis(float x1,float y1,float x2,float y2) { return sqrt(pow(x1-x2,2)+pow(y1-y2,2)); } int main() { freopen("b.in","r",stdin); freopen("b.out","w",stdout); cin>>n>>r; for(int i=1;i<=n;i++) cin>>p[i][1]>>p[i][2]; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { if(pd(i,j)<0||pd(j,i)<0) { float d=min(pow(p[i][1],2)+pow(p[i][2],2),pow(p[j][1],2)+pow(p[j][2],2)); if(d>(r*r)) ans++; } else { float d=cross(p[i][1],p[i][2],p[j][1],p[j][2])/dis(p[i][1],p[i][2],p[j][1],p[j][2]); if(d>r) ans++; } } cout<<ans; fclose(stdin); fclose(stdout); }
正解:
gtc老师说本来就没打算有人写出来......
要在圆弧上求区间交
好厉害的样子啊
并没有标程(太难了
T3:
裸裸地凸包模板
考试代码(100分):
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int n; struct point { float x; float y; }p[10010]; int q[40040]; int top; float cross(float x1,float y1,float x2,float y2) { float d=x1*y2-x2*y1; return d; } bool cmp(point a,point b) { if(a.x!=b.x) return a.x<b.x; else return a.y<b.y; } int main() { freopen("c.in","r",stdin); freopen("c.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) cin>>p[i].x>>p[i].y; sort(1+p,1+p+n,cmp); for(int i=1;i<=n;i++) { while(top>=2&&cross(p[q[top-1]].x-p[q[top]].x,p[q[top-1]].y-p[q[top]].y,p[q[top-1]].x-p[i].x,p[q[top-1]].y-p[i].y)<=0) top--; q[++top]=i; } int k=top; for(int i=n-1;i>=1;i--) { while(top>k&&cross(p[q[top-1]].x-p[q[top]].x,p[q[top-1]].y-p[q[top]].y,p[q[top-1]].x-p[i].x,p[q[top-1]].y-p[i].y)<=0) top--; q[++top]=i; } if(n>1) top--; cout<<top; fclose(stdin); fclose(stdout); }
晚上机房划水
回宿舍看银河护卫队
Day5
早上起迟了......
8:00起床 然而8:00就上课了
gtc老师的课迟到真的很不好意思啊
一早上的DP 脑子又炸了
状压DP还是不太懂
T1:
第一题挺水的
40min敲完线性DP
考试代码(100分):
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char s1[2005],s2[2005]; int f[2005][2005]; int n,m; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); scanf("%s%s",s1,s2); n=strlen(s1); m=strlen(s2); for(int i=1;i<=n;i++) f[i][0]=i; for(int i=1;i<=m;i++) f[0][i]=i; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(s1[i-1]==s2[j-1]) f[i][j]=f[i-1][j-1]; else { f[i][j]=min(f[i][j-1]+1,f[i-1][j]+1); f[i][j]=min(f[i][j],f[i-1][j-1]+1); } } cout<<f[n][m]; fclose(stdin); fclose(stdout); }
T2:
说好的都考DP呢?
又被耍了一波
把正解给改成超时的了.......(难受
考试代码(40分):
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,sum,ans=1; int f[1000010]; struct maps { int h; int x; int y; }map[1000010]; bool cmp(maps a,maps b) { return a.h<b.h; } int pd(int i,int j) { if(map[i].x+1==map[j].x&&map[i].y==map[j].y) return 1; if(map[i].x-1==map[j].x&&map[i].y==map[j].y) return 1; if(map[i].x==map[j].x&&map[i].y+1==map[j].y) return 1; if(map[i].x==map[j].x&&map[i].y-1==map[j].y) return 1; return 0; } int main() { freopen("b.in","r",stdin); freopen("b.out","w",stdout); cin>>n>>m; for(int i=1;i<=n*m;i++) f[i]=1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>map[++sum].h; map[sum].x=i; map[sum].y=j; } sort(1+map,1+map+n*m,cmp); for(int i=2;i<=n*m;i++) { for(int j=1;j<i;j++) { if(pd(i,j)&&map[i].h>map[j].h) { f[i]=max(f[i],f[j]+1); } } ans=max(ans,f[i]); } cout<<ans; fclose(stdin); fclose(stdout); }
正解:
要把cincout改成scanf啥的
不然会T6个点
#include<iostream> #include<cmath> using namespace std; int a[201][201]; int b[201][201]; int dx[4]={0,0,1,-1}, dy[4]={1,-1,0,0}; int n,m; int maxn=0; int search(int x,int y) { if(b[x][y]) return b[x][y]; b[x][y]=1; for(int i=0;i<4;i++) { int x1=x+dx[i]; int y1=y+dy[i]; if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&a[x1][y1]>a[x][y]) b[x][y]=max(b[x][y],1+search(x1,y1)); } return b[x][y]; } int main() { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { maxn=max(maxn,search(i,j)); } cout<<maxn; }
T3:
说好的状压呢?
虽然就算是状压也不会写
暴力打表过了2个点
考试代码(20分):
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mod 9999973; using namespace std; int n,m; int main() { freopen("c.in","r",stdin); freopen("c.out","w",stdout); cin>>n>>m; if(n==1) { for(int i=1;i<=8;i++) if(m==i) cout<<(1+m-1)*(m-1)/2+m+1; } if(n==2) { for(int i=1;i<=8;i++) if(m==i) cout<<((1+m-1)*(m-1)/2+m+1)*2; } else cout<<666; fclose(stdin); fclose(stdout); }
正解:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; typedef long long ll; const int MAXN = 101; const int MOD = 9999973; int n,m; ll dp[MAXN][MAXN][MAXN]; inline int C( int num ) { // 相当于C(num,2) return num*(num-1)/2; } int main() { scanf( "%d%d", &n, &m ); dp[0][0][0] = 1; for( int i = 0; i < n; ++i ) // 放第i+1行 for( int j = 0; j <= m; ++j ) // 有1个棋子的列数 for( int k = 0; j+k <= m; ++k ) if( dp[i][j][k] ) { // 有2个棋子的列数 dp[i+1][j][k] = ( dp[i+1][j][k] + dp[i][j][k] ) % MOD; // 不放 if( m-j-k >= 1 ) dp[i+1][j+1][k] = ( dp[i+1][j+1][k] + dp[i][j][k]*(m-j-k) ) % MOD; // 放一个,在没有棋子的那一列 if( j >= 1 ) dp[i+1][j-1][k+1] = ( dp[i+1][j-1][k+1] + dp[i][j][k]*j ) % MOD; // 放一个,在有一个棋子的那一列 if( m-j-k >= 2 ) dp[i+1][j+2][k] = ( dp[i+1][j+2][k] + dp[i][j][k]*C(m-j-k) ) % MOD; // 放两个,都在没有棋子的两列 if( m-j-k >= 1 && j >= 1 ) dp[i+1][j][k+1] = ( dp[i+1][j][k+1] + dp[i][j][k]*(m-j-k)*j ) % MOD; // 放两个,一个在没有棋子的列,一个在有一个棋子的列 if( j >= 2 ) dp[i+1][j-2][k+2] = ( dp[i+1][j-2][k+2] + dp[i][j][k]*C(j) ) % MOD; // 两个,在一个棋子的列 } ll ans = 0; for( int i = 0; i <= m; ++i ) // 有1个棋子的列 for( int j = 0; i+j <= m; ++j ) { // 2个棋子的列 ans = ( ans + dp[n][i][j] ) % MOD; } printf( "%lld ", ans ); return 0; }
下午下课加了gtc老师的QQ
人挺好的(原来以为很凶的样子
说我们有事可以问他
他要去福州上课了
跟我们说了再见
晚上机房没老师管
又颓了一波
Day6
今天老师换成sjh老师啦
看起来好像......蛮有代沟的样子(不像大学生啊
来自中国科学院大学???
据说是一个比清北还要牛逼的大学(崇拜脸
早上上图论
又是划水的一天
唯一想听的差分约束系统竟然这么简单???
虽然思路都会
但是好久没做图论板子都忘光光了额......
T1:
裸的最短路
算了一下最简单的Floyed好像不会超时
但是......但是它还是爆了只有40分(我好菜啊
考试代码(40分):
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int n,m; float len; float ele[1005][3]; float map[1005][1005]; float pd(float x1,float y1,float x2,float y2,float x3,float y3) { if(pow(x3-x2,2)+pow(y3-y2,2)>=pow(len,2)) return 0; if(pow(x3-x1,2)+pow(y3-y1,2)>=pow(len,2)) return 0; } float dis(int f,int s) { float x1=ele[f][1]; float y1=ele[f][2]; float x2=ele[s][1]; float y2=ele[s][2]; float d=sqrt(pow(x1-x2,2)+pow(y1-y2,2)); return d; } int main() { scanf("%d%d%f",&n,&m,&len); for(int i=1;i<=n;i++) cin>>ele[i][1]>>ele[i][2]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j) map[i][j]=map[j][i]=0; else { if(dis(i,j)>len) map[i][j]=map[j][i]=99999999; else map[i][j]=map[j][i]=dis(i,j); } } for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; map[x][y]=0; map[y][x]=0; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j-++) { if(map[i][j]>map[i][k]+map[k][j]) map[i][j]=map[i][k]+map[k][j]; } if(map[1][n]==99999999) cout<<"-1"; else cout<<floor(map[1][n]*1000); }
正解:
用SPFA做最短路
或者Floyed砍掉一半边
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int n,m,cnt; double ans,len; int exist[500005]; int team[2000020]; int head[500005]; double dis[500005]; int t=0,w=1; struct ele { double x; double y; }ele[100005]; struct edge { int next; int to; double w; }e[5000005]; void add(int u,int v,double w) { e[++cnt].w=w; e[cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; } double dist(int i,int j) { double x1=ele[i].x; double y1=ele[i].y; double x2=ele[j].x; double y2=ele[j].y; double d=hypot(x1-x2,y1-y2); return d; } int main() { cin>>n>>m>>len; for(int i=1;i<=n;i++) cin>>ele[i].x>>ele[i].y; for(int i=1;i<=n;i++) dis[i]=99999999; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { if(dist(i,j)<=len) { add(i,j,dist(i,j)); add(j,i,dist(i,j)); } } for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; add(x,y,0); add(y,x,0); } dis[1]=0; team[1]=1; while(t<w) { t++; int u=team[t]; exist[u]=0; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; if(dis[v]>dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; if(!exist[v]) { w++; exist[v]=1; team[w]=v; } } } } if(dis[n]==99999999) cout<<"-1"; else cout<<int(dis[n]*1000); }
T2:
最大流......
思路完全正确(代码完全忘却
打了个表和随机数
考试代码(10分):
#include<iostream> #include<cstdlib> #include<ctime> #include<cstdio> using namespace std; int n,k; bool f[21][21]; int main() { scanf("%d%d",&n,&k); if(k==0) cout<<n; else { if(k==1) cout<<1; else { srand((unsigned)time(NULL)); cout<<rand()%10<<' '; } } }
正解:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<deque> #include<cstring> #define INF 1e9 using namespace std; int n,k,S,T,V[120000],nex[120000],las[4000],W[120000],c[4000],tot=1,L=0,R=1e9; char s[550][550]; void addedge(int t1,int t2,int t3) { V[++tot]=t2;nex[tot]=las[t1];las[t1]=tot;W[tot]=t3; V[++tot]=t1;nex[tot]=las[t2];las[t2]=tot;W[tot]=0; } bool bfs() { bool flag=0; deque<int>que; que.clear(); memset(c,0,sizeof(c)); c[S]=1;que.push_back(S); while(!que.empty()) { int x=que.front();que.pop_front(); if(x==T)flag=1; int h=las[x]; while(h) { if(W[h]>0&&!c[V[h]]) c[V[h]]=c[x]+1,que.push_back(V[h]); h=nex[h]; } } return flag; } int dfs(int x,int p) { if(x==T||!p)return p; int flow=0,fl; for(int i=las[x];i;i=nex[i]) if(c[x]+1==c[V[i]]&&W[i]) { fl=dfs(V[i],min(p-flow,W[i])); flow+=fl;W[i^1]+=fl;W[i]-=fl; if(flow==p)return flow; } return flow; } bool build(int mid) { memset(las,0,sizeof(las)); memset(W,0,sizeof(W)); memset(V,0,sizeof(V)); memset(nex,0,sizeof(nex)); tot=1; for(int i=1;i<=n;++i)lj(S,i,mid); for(int i=2*n+1;i<=3*n;++i)lj(i,T,mid); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) { if(s[i][j]=='Y')lj(i,2*n+j,1); else { lj(n+i,3*n+j,1); } } for(int i=1;i<=n;i++)lj(i,i+n,k),lj(3*n+i,2*n+i,k); int ans=0; while(bfs())ans+=dfs(S,INF); return (ans==mid*n); } int main() { scanf("%d%d",&n,&k); S=4*n+1;T=4*n+2; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j)scanf(" %c",&s[i][j]); while(L<R) { int mid=(L+R+1)>>1; if(build(mid))L=mid; else R=mid-1; } printf("%d",L); return 0; }
T3:
完全没有思路......
考试放弃
正解:
用一种玄学的进制存图
然后上下移动不管 因为反正都要走回去
所以观察左右移动就行
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<queue> using namespace std; #define N 55 #define inf 1e9 int n,m,map[N][N],tot,toti,MaxS,f[N][N][1050],g[N][N],ok,ans[12]; int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; //四个方向走 bool inq[N][N][1050];char c[N][N]; struct node { int x,y,S; node(){}; node(int _x,int _y,int _S) {x=_x,y=_y,S=_S;} }; queue<node>q; int main(){ // freopen("1.in","r",stdin); while(scanf("%s",c[++n]+1)!=EOF); m=strlen(c[--n]+1); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(c[i][j]!='.'){ //tot 非.格子的个数,toti i格子的个数 map[i][j]=++tot; if(c[i][j]=='X') //二进制,1对应的那位为X ok|=1<<tot-1; else toti++; } //map数组表示从ij格子先向上j走到0,再i走到0,新圈住的非.格 //例如样例: //102 //142 //942 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ g[i][j]=g[i-1][j]; if(map[i][j]) g[i][j]|=1<<map[i][j]-1; } MaxS=(1<<tot)-1; //f[i][j][k]表示从ij格子返回来圈主k(二进制有多少个1)个 非.格子所走的步数 //inq数组表示是否访问过 for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) for(int k=0;k<=MaxS;k++) f[i][j][k]=inf; f[0][0][0]=0,inq[0][0][0]=1,q.push(node(0,0,0)); while(!q.empty()){ node top=q.front(); q.pop(); inq[top.x][top.y][top.S]=0; cout<<top.x<<"-"<<top.y<<"-"<<top.S<<":"<<f[top.x][top.y][top.S]<<endl; for(int k=1;k<=4;k++){ int nx=top.x+dx[k],ny=top.y+dy[k],nS=top.S; if(nx<0||nx>n||ny<0||ny>m) continue; //假设到xy点后,返回都是先走y再走x,所以只需要更新k=3和4 //3往左走判断左边格子新圈住的非.格子 if(k==3) nS^=g[top.x][top.y]; //4往右走判断右边格子新圈住的非.格子 if(k==4) nS^=g[nx][ny]; //更新f数组 if(f[nx][ny][nS]>f[top.x][top.y][top.S]+1){ f[nx][ny][nS]=f[top.x][top.y][top.S]+1; //打标记,当前状态没访问过则入队列 if(!inq[nx][ny][nS]) inq[nx][ny][nS]=1,q.push(node(nx,ny,nS)); } } } for(int i=1;i<=toti;i++) ans[i]=inf; for(int i=0;i<=MaxS;i++) if(!(i&ok)){ int cnt=0; //计算多少个I, for(int j=0;j<tot;j++) if((i>>j)&1) cnt++; //f[0][0][i]表示圈主i对应二进制为1的I所需的步数 ans[cnt]=min(ans[cnt],f[0][0][i]); } for(int i=1;i<=toti;i++) printf("%d ",ans[i]); return 0; }
晚上台风 没去吃饭
没有电影看好无聊啊
晚上偷吃泡面
Day7
最后一天的早上
又迟到了
早上前面一个小时讲了Day6的几道题
还有图论的几道例题
然后上了数据结构 线段树啥的
但是!
我最想听的ST表和树上倍增居然因为时间不够没讲了QAQ
中午没怎么休息 因为下午4点就可以回家
13:00就开始考试了
T1
哇这最小公倍数水水的
T2
哇这题看不懂打个暴力30分
T3
哇这不是SPFA微调一下就可以了
结果......爆零......
T1谜一样的后来对了标程
除了定义不一样 其他都一样 可是莫名其妙的结果被零整除???
T2就一点点的数据超内存???
T3一开始没想到正解 原来是最小生成树
培训就在这最谜的一天结束了......