首页 > 代码库 > 计蒜之道复赛 B D F
计蒜之道复赛 B D F
B题是一个简单的模拟
求一下两个点中间在上deta的整数点
然后更新一下每个点的最后一次经过就好了
1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(x) cerr<<#x<<"=="<<(x)<<endl 4 using namespace std; 5 6 const int maxn=300+10; 7 8 int gcd(int a,int b){return a?gcd(b%a,a):b;} 9 int abs(int a){if(a>0)return a;return -a;}10 11 int a[maxn][maxn];12 13 int main()14 {15 int n,m;16 scanf("%d%d",&n,&m);17 cl(a,0);18 for(int i=1;i<=n;i++)19 {20 int x1,y1,x2,y2,dx,dy;21 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);22 dx=x2-x1;23 dy=y2-y1;24 int k=gcd(abs(dx),abs(dy));25 dx/=k,dy/=k;26 x2+=dx;27 while(x1!=x2)28 {29 // debug(x1),debug(y1);30 a[x1][y1]=i;31 x1+=dx,y1+=dy;32 }33 }34 int q;35 scanf("%d",&q);36 while(q--)37 {38 int x,y;39 scanf("%d%d",&x,&y);40 printf("%d\n",a[x][y]);41 }42 return 0;43 }/*44 45 5 846 2 5 5 247 5 2 3 848 8 4 1 449 2 2 5 850 8 7 4 151 452 3 453 5 254 6 455 3 556 57 */
D是一个最短路
需要注意的是每个城市群需要加两个点u‘和u‘‘
每个群内的城市连自己的城市群是
u‘->v
v->u‘‘
然后每个城市群之间
u‘->v‘‘
v‘->u‘‘
直接跑一遍spfa就行
需要注意的是:
1.n和m没有规定谁大谁小 所以加点的时候n*2+i和n+i是会冲突的
2.因为最大的值是2e5*2e6>2^31-1 所以ans要用ll存
3.由于上一点的存在 inf也要改……
1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(x) cerr<<#x<<"=="<<(x)<<endl 4 using namespace std; 5 typedef long long ll; 6 7 const int MAXN=4e5+10; 8 const ll INF=2e12; 9 10 struct Edge 11 { 12 int v; 13 int cost; 14 Edge(int _v=0,int _cost=0):v(_v),cost(_cost) {} 15 }; 16 17 vector<Edge>E[MAXN]; 18 19 void addedge(int u,int v,int w) 20 { 21 E[u].push_back(Edge(v,w)); 22 } 23 24 bool vis[MAXN]; 25 int cnt[MAXN]; 26 ll dist[MAXN]; 27 int n,m; 28 int start,over; 29 30 ll SPFA(int start,int n) 31 { 32 for(int i=0;i<n+m*2+10;i++) 33 { 34 dist[i]=INF; 35 vis[i]=false; 36 } 37 vis[start]=true; 38 dist[start]=0; 39 queue<int>que; 40 while(!que.empty())que.pop(); 41 que.push(start); 42 memset(cnt,0,sizeof(cnt)); 43 cnt[start]=1; 44 while(!que.empty()) 45 { 46 int u=que.front(); 47 que.pop(); 48 vis[u]=false; 49 for(int i=0; i<E[u].size(); i++) 50 { 51 int v=E[u][i].v; 52 if(dist[v]>dist[u]+E[u][i].cost) 53 { 54 dist[v]=dist[u]+E[u][i].cost; 55 if(!vis[v]) 56 { 57 vis[v]=true; 58 que.push(v); 59 if(++cnt[v]>n) return -1; 60 } 61 } 62 } 63 } 64 return dist[over]; 65 } 66 67 int main() 68 { 69 scanf("%d%d",&n,&m); 70 for(int i=1;i<=m;i++) 71 { 72 int k; 73 scanf("%d",&k); 74 for(int j=0;j<k;j++) 75 { 76 int x; 77 scanf("%d",&x); 78 addedge(x,n+m+i,0); 79 addedge(n+i,x,0); 80 } 81 } 82 int m1; 83 scanf("%d",&m1); 84 for(int i=0;i<m1;i++) 85 { 86 int u,v,w; 87 scanf("%d%d%d",&u,&v,&w); 88 addedge(u,v,w); 89 addedge(v,u,w); 90 } 91 int m2; 92 scanf("%d",&m2); 93 for(int i=0;i<m2;i++) 94 { 95 int u,v,w; 96 scanf("%d%d%d",&u,&v,&w); 97 addedge(n+m+u,n+v,w); 98 addedge(n+m+v,n+u,w); 99 }100 scanf("%d%d",&start,&over);101 ll ans=SPFA(start,n);102 printf("%lld\n",ans>=INF?-1:ans);103 return 0;104 }/*105 106 5 4107 2 5 1108 2 2 4109 1 3110 2 3 4111 2112 1 2 9113 1 5 18114 2115 1 2 6116 1 3 10117 1 5118 119 */
F是一个状压dp
(虽然没有16这么性感的数字 但是18也很明显了~
第一维表示当前状态 01表示是否删除
第二维表示已经删除的步数
用l r来枚举区间
数据范围不是很大(2^n)*n*n是可以容忍的
(也是调了好久啊……
1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(x) cerr<<#x<<"=="<<(x)<<endl 4 using namespace std; 5 typedef long long ll; 6 7 const int maxn=20; 8 const int mod=1000000007; 9 10 int gcd(int a,int b)11 {12 return a?gcd(b%a,a):b;13 }14 15 bool check(int x,int y)16 {17 return x&(1<<y);18 }19 20 int n,k;21 int a[maxn];22 int dp[(1<<maxn)][maxn];23 24 void solve()25 {26 for(int i=0; i<(1<<n); i++)27 {28 for(int l=0; l<n; l++)29 {30 int tmp=i;31 if(check(i,l))32 {33 int tmp1=a[l];34 for(int r=l; r<n; r++)35 {36 if(check(i,r))37 {38 tmp^=(1<<r);39 tmp1=gcd(tmp1,a[r]);40 if(tmp1<k) break;41 for(int j=1; j<=n; j++)42 {43 dp[i][j]=(dp[i][j]+dp[tmp][j-1])%mod;44 }45 }46 }47 }48 }49 }50 }51 52 int main()53 {54 scanf("%d%d",&n,&k);55 cl(a,0),cl(dp,0);56 for(int i=0; i<n; i++)57 {58 scanf("%d",&a[i]);59 }60 dp[0][0]=1;61 solve();62 ll ans=0;63 for(int i=1; i<=n; i++)64 {65 ans+=1ll*i*dp[(1<<n)-1][i];66 ans%=mod;67 }68 printf("%lld\n",ans);69 return 0;70 }/*71 72 4 173 1 1 1 174 75 */
计蒜之道复赛 B D F
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。