标签:alpha kruskal search fat cat 路径 -o oid +=
大意:用最短路径来抓住所有的稀有精灵,DFS求最短路
#include <bits/stdc++.h> #define mem(a) memset(a,0,sizeof(a)) #define forn(i,n) for(int i=0;i<n;++i) #define for1(i,n) for(int i=1;i<=n;++i) #define IO std::ios::sync_with_stdio(false); std::cin.tie(0) #define ll long long using namespace std; const int maxn=22; int n,m,all_mask; int x[maxn],y[maxn],dist[maxn][maxn]; string name[maxn]; int dp[maxn][1<<maxn],p[maxn]; int dfs(int k,int mask) { if(dp[k][mask]!=-1) return dp[k][mask]; if(mask==all_mask) return dist[k][n]; int &ans=dp[k][mask]; ans=1e9; forn(i,n) { if((1<<i)& mask) continue; ans=min(ans,dist[k][i]+dfs(i,mask|p[i])); } return ans; } int main() { cin>>n; forn(i,n) cin>>x[i]>>y[i]>>name[i]; forn(i,n) forn(j,n) if(name[i]==name[j]) p[i]|=1<<j; x[n]=y[n]=0; p[n]=1<<n; all_mask=(1<<n)-1; for(int i=0;i<=n;++i) for(int j=0;j<=n;++j) dist[i][j]=abs(x[i]-x[j])+abs(y[i]-y[j]); memset(dp,-1,sizeof(dp)); cout<<dfs(n,0)<<endl; return 0; }
C. Urban Design
解题过程:只要使用二分定理,只要判断两个点在哪些线的一侧,根据线的个数的奇偶来判断是否在相同的一块区域之中
#include <bits/stdc++.h> #define mem(a) memset(a,0,sizeof(a)) #define forn(i,n) for(int i=0;i<n;++i) #define for1(i,n) for(int i=1;i<=n;++i) #define IO std::ios::sync_with_stdio(false); std::cin.tie(0) #define ll long long #define PI 3.14159265358979323846 using namespace std; const int maxn=2e4+50; int n,m,sx,sy,ans; struct vec{int x1,x2,y1,y2,ans;}a[maxn],b[maxn]; ll cross(int x1,int y1,int x2,int y2){return 1LL*x1*y2-1LL*x2*y1;} bool PointAndSide(const vec& line,const vec& pts) { int ox=line.x1,oy=line.y1; ll dx=line.x2-line.x1,dy=line.y2-line.y1; ll a=cross(pts.x1-ox,pts.y1-oy,dx,dy); ll b=cross(pts.x2-ox,pts.y2-oy,dx,dy); assert(a!=0&&b!=0); return (a<0&&b>0)||(a>0&&b<0); } int main() { cin>>n; forn(i,n) cin>>a[i].x1>>a[i].y1>>a[i].x2>>a[i].y2; cin>>m; forn(i,m) cin>>b[i].x1>>b[i].y1>>b[i].x2>>b[i].y2; forn(i,n) forn(j,m) if(PointAndSide(a[i],b[j])) b[j].ans++; forn(i,m) if(b[i].ans%2) cout<<"different"<<endl; else cout<<"same"<<endl; return 0; }
G. Sheba‘s Amoebas
解题思路:没啥幺蛾子,直接DFS爆搜,直接过,数据量也不大
#include <bits/stdc++.h> #define mem(a) memset(a,0,sizeof(a)) #define forn(i,n) for(int i=0;i<n;++i) #define for1(i,n) for(int i=1;i<=n;++i) #define IO std::ios::sync_with_stdio(false); std::cin.tie(0) #define ll long long using namespace std; const int maxn=1e3+50; char pic[110][110]; int dir[8][2] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1} }; bool vis1[110][110],vis2[110][110]; int n,m,sx,sy,ans; bool check(int x, int y) { if(x >= 1 && x <= n & y >= 1 && y <= m && pic[x][y] == ‘#‘ && !vis1[x][y] & ! vis2[x][y]) return true; return false; } void dfs(int x,int y,int cnt) { bool flag=false; for(int i=0; i<8; ++i) { int tx=x+dir[i][0],ty=y+dir[i][1]; if(check(tx,ty)) { vis1[tx][ty]=vis2[tx][ty]=true; dfs(tx,ty,cnt+1); vis1[tx][ty]=0; flag=true; } } if(!flag&&cnt>1) { for(int i = 0; i <= 7; i++) { int tx = x + dir[i][0], ty = y + dir[i][1]; if(tx == sx && ty == sy) { ans++; return; } } } } int main() { while(cin>>n>>m) { mem(vis1); mem(vis2); for1(i,n) for1(j,m) cin>>pic[i][j]; ans=0; for1(i,n) for1(j,m) { if(!vis1[i][j]&&pic[i][j]==‘#‘) { mem(vis1); vis1[i][j]=vis2[i][j]=1; sx=i,sy=j; dfs(i,j,1); } } cout<<ans<<endl; } return 0; }
H. Zebras and Ocelots
解题思路:将整个排序反过来,然后看O的位置,O在第i位就会产生 2^i 的步骤,用快速幂加一下就OK
#include <bits/stdc++.h> #define mem(a) memset(a,0,sizeof(a)) #define forn(i,n) for(int i=0;i<n;++i) #define for1(i,n) for(int i=1;i<=n;++i) #define IO std::ios::sync_with_stdio(false); std::cin.tie(0) #define ll long long using namespace std; const int maxn=1e3+50; int n,m,sx,sy,ans; char c; ll quick_pow(ll a,ll b) { ll res=1; while(b) { if(b&1) res*=a; a=a*a; b=b>>1; } return res; } int main() { while(cin>>n) { ll ans=0; string str; forn(i,n) { cin>>c; str+=c; } //cout<<str<<endl; reverse(str.begin(),str.end()); for(int i=0;i<str.size();++i) { if(str[i]==‘O‘) ans+=quick_pow(2,i); } cout<<ans<<endl; } return 0; }
I. Racing Around the Alphabet
解题思路:纯模拟题,就是依次走,计算最短路径和就行了
#include <bits/stdc++.h> #define mem(a) memset(a,0,sizeof(a)) #define forn(i,n) for(int i=0;i<n;++i) #define for1(i,n) for(int i=1;i<=n;++i) #define IO std::ios::sync_with_stdio(false); std::cin.tie(0) #define ll long long #define PI 3.14159265358979323846 using namespace std; const int maxn=1e3+50; int n,m,sx,sy,ans; double perlen,res; char lists[28]={‘ ‘,‘\‘‘,‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘,‘G‘,‘H‘,‘I‘,‘J‘,‘K‘,‘L‘,‘M‘,‘N‘,‘O‘,‘P‘,‘Q‘,‘R‘,‘S‘,‘T‘,‘U‘,‘V‘,‘W‘,‘X‘,‘Y‘,‘Z‘}; char dim[200]; int searchx(char x) { for(int i=0;i<28;++i) { if(lists[i]==x) return i+1; } } int main() { perlen=PI*60.0/28.0; while(cin>>n) { getchar(); while(n--) { res=0.0; string str; getline(cin,str); res+=str.size(); for(int i=0;i<str.size()-1;++i) { int a=searchx(str[i])-searchx(str[i+1]); if(a<0) a=min(abs(a),abs(a+28)); else a=min(a,28-a); //cout<<a<<endl; res+=perlen*a/15.0; } printf("%.10f\n",res); } } return 0; }
J. Lost Map
解题思路:最小生成树,模板题,随便套Kruskal和Prim随便用一个就行了
#include <bits/stdc++.h> using namespace std; #define MAX_N 2501 struct edge { int from,to; long long cost; }E[MAX_N*MAX_N]; int N,M;//N是点的个数,M是边的数量 int father[MAX_N]; void init() { for(int i=1;i<=N;i++)father[i]=i; } int findd(int x) { if(x==father[x])return x; return father[x]=findd(father[x]); } bool same(int x,int y) { return findd(x)==findd(y); } void unite(int x,int y) { int u=findd(x),v=findd(y); if(u==v)return; father[u]=v; return; } bool cmp(edge a,edge b) { return a.cost<b.cost; } void Kruskal() { sort(E+1,E+1+M,cmp); for(int i=1;i<=M;i++) { if(same(E[i].from,E[i].to))continue; unite(E[i].from,E[i].to); cout<<E[i].from<<" "<<E[i].to<<endl; } return; } int main() { int x; while(~scanf("%d",&N)) { M=0; init(); for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { scanf("%d",&x); if(x!=0) { M++; E[M].from=i+1; E[M].to=j+1; E[M].cost=x; } } } Kruskal(); } return 0; }
ICPC North Central NA Contest 2017 部分题解
标签:alpha kruskal search fat cat 路径 -o oid +=
原文地址:https://www.cnblogs.com/bethebestone/p/12383619.html