2017年上海金馬五校程序設計競賽
阿新 • • 發佈:2017-06-05
ear lld iter style double top != -1 bre
A
STEED 這個字符串可以任意變換位子
找到第n個
深搜 遍歷所有可能字符串 然後放到set維護 第n個就可以了
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> using namespace std; #define ll long long #defineView Codeinf 1000000007 string z="STEED"; bool vis[5]; set<string>s1; void dfs(int ind,string a) { int ok=0; for(int i=0;i<5;i++) { if(vis[i]==0) { ok=1; } } if(ok==0) { //cout<<a<<endl; s1.insert(a); return ; }for(int i=0;i<5;i++) { if(!vis[i]) { vis[i]=1; dfs(i,a+z[i]); vis[i]=0; } } } int main() { for(int i=0;i<5;i++) { string a=""; a=a+z[i]; vis[i]=1; dfs(i,a); vis[i]=0; } intn; while(scanf("%d",&n)!=EOF) { int i=1; for(set<string>::iterator j=s1.begin();i<=n;i++,j++) { if(i==n) cout<<*j<<endl; } } return 0; }
B
n*n矩陣
從左上角走到右下角
*到*費用是1 #到其他地方費用2
問最小費用
bfs+優先隊列 步數小的優先 步數相同 *優先
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> #include<math.h> #include<queue> #include<vector> using namespace std; #define ll long long #define inf 1000000007 #define MAXN 20010 bool vis[55][55]; char z[55][55]; struct node { int x,y,step; }; struct cmp1{ bool operator ()(node a,node b){ if(a.step==b.step) { if(z[a.x][a.y]==‘*‘) return 0; return 1; } return a.step>b.step;//最小值優先 } }; priority_queue<node ,vector<node >,cmp1>q1; int s1[4]={1,-1,0,0}; int s2[4]={0,0,1,-1}; int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%s",z[i]+1); memset(vis,0,sizeof(vis)); while(!q1.empty()) q1.pop(); node a; a.x=1; a.y=1; a.step=0; q1.push(a); vis[a.x][a.y]=1; int mx=inf; while(!q1.empty()) { node now=q1.top(); if(now.x==n&&now.y==n) { mx=min(mx,now.step); } q1.pop(); for(int i=0;i<4;i++) { node b; b.x=now.x+s1[i]; b.y=now.y+s2[i]; if(b.x>=1&&b.x<=n&&b.y>=1&&b.y<=n&&vis[b.x][b.y]==0) { vis[b.x][b.y]=1; if(z[now.x][now.y]==‘#‘) b.step=now.step+1; else { if(z[b.x][b.y]==‘#‘) b.step=now.step+1; else b.step=now.step; } // printf("%d %d %d %d %d %d\n",now.x,now.y,now.step,b.x,b.y,b.step); q1.push(b); } } } printf("%d\n",mx); } return 0; }View Code
C
n然後n個數字 要在每個數字前面加 一個 + 或者 - 問有多少個不同的結果
暴力 去同
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> using namespace std; #define ll long long #define inf 1000000007 #define MAXN 20010 set<ll>s1; ll z[25]; int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) scanf("%lld",&z[i]); int en=1<<n; s1.clear(); for(int i=0;i<en;i++) { ll ans=0; for(int j=0;j<n;j++) { if(i&(1<<j)) ans=ans+z[j]; else ans=ans-z[j]; } s1.insert(ans); } printf("%d\n",s1.size()); } return 0; }View Code
E 最長回文字串 暴力的
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> using namespace std; #define ll long long #define inf 1000000007 #define MAXN 20010 char z[55]; int main() { while(scanf("%s",z)!=EOF) { int len=strlen(z); int mx=0; for(int i=0;i<len;i++) { for(int j=i;j<len;j++) { int a=i; int b=j; for(;a<=b;a++,b--) { if(z[a]!=z[b]) break; } if(a>b) mx=max(mx,j-i+1); } } printf("%d\n",mx); } return 0; }View Code
G 給你n *m矩陣 每次可以向下或者向右走一不 不能走的人輸掉
第二個人開始有一次機會 去掉一個點 n+m-2 後手贏 那麽 後手可以隨便 放一個贏的
否則 max(n,m)-min(n,m)>=2 後手贏 否則先手贏
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> #include<math.h> #include<queue> #include<vector> using namespace std; #define ll long long #define inf 1000000007 #define MAXN 20010 int main() { ll n,m; while(scanf("%lld%lld",&n,&m)!=EOF) { if((n+m)%2==1){ if(max(n,m)-min(m,n)>=2) printf("YES\n"); else printf("NO\n"); } else printf("YES\n"); } return 0; }View Code
H n 個數 長度為k的窗子 求最大值 最大平均值 最小方差
最大值單調隊列 平均的話 前綴 方差 也是前綴 前綴平方 化簡下就可以
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> #include<math.h> #include<queue> #include<vector> using namespace std; #define ll long long #define inf 1000000007 #define MAXN 10000100 double z[MAXN]; struct { double w; int ind; }q[MAXN]; double sum[MAXN]; double sum1[MAXN]; int main() { int n,k; while(scanf("%d%d",&n,&k)!=EOF) { double mi; double mx; sum[0]=sum1[0]=0; for(int i=1;i<=n;i++) { scanf("%lf",&z[i]); sum[i]=sum[i-1]+z[i]; sum1[i]=sum1[i-1]+z[i]*z[i]; if(i==k) { mi=sum[i]/k; mx=sqrt(sum1[i]/k-2*mi*sum[i]/k+mi*mi); } else if(i>k) { double u=(sum[i]-sum[i-k])/k; mi=max(mi,u); mx=min(mx,sqrt((sum1[i]-sum1[i-k])/k-2*u*(sum[i]-sum[i-k])/k+u*u)); } } double ans=0; int fr=1; int sz=1; q[1].w=z[1]; q[1].ind=1; for(int i=2;i<k;i++) { while(sz>=fr&&q[sz].w<z[i]) sz--; sz++; q[sz].w=z[i]; q[sz].ind=i; } for(int i=k;i<=n;i++) { while(sz>=fr&&q[sz].w<z[i]) sz--; sz++; q[sz].w=z[i]; q[sz].ind=i; while(q[fr].ind<i-k+1) fr++; ans=ans+q[fr].w; } printf("%.1lf %.1lf %.1lf\n",1.0*ans/(n-k+1),mi,mx); } return 0; }View Code
I
求歐拉函數
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> #include<math.h> using namespace std; #define ll long long #define inf 1000000007 #define MAXN 20010 int ph(int a) { int b=a; int c=b; for(int i=2;i<=sqrt(a);i++) { if(b%i==0) { while(b%i==0) b=b/i; c=c/i*(i-1); } } if(b!=1) c=c/b*(b-1); return c; } int main() { int n; while(scanf("%d",&n)!=EOF) { printf("%d\n",ph(n)); } return 0; }View Code
K題
蛇形填數 維護左右上下邊界
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> #include<math.h> #include<queue> #include<vector> using namespace std; #define ll long long #define inf 1000000007 #define MAXN 20010 int z[10085]; int x[105][105]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n*m;i++) scanf("%d",&z[i]); int l,c,t,d; l=c=1; int r1=m; t=2; int t1=n; int cnt=1; while(cnt<=n*m) { for(int i=c;i<=r1;i++) x[l][i]=z[cnt++]; if(cnt>n*m) { break; } for(int i=l+1;i<=t1;i++) x[i][r1]=z[cnt++]; if(cnt>n*m) { break; } for(int i=r1-1;i>=c;i--) x[t1][i]=z[cnt++]; if(cnt>n*m) { break; } for(int i=t1-1;i>l;i--) x[i][c]=z[cnt++]; if(cnt>n*m) { break; } l++; c++; t1--; r1--; } for(int i=1;i<=n;i++) { for(int j=1;j<m;j++) printf("%d ",x[i][j]); printf("%d\n",x[i][m]); } } return 0; }View Code
O
n 然後2*n個數 分成n組 每組2個數 然後求每組差的絕對值的和 最小
排序
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<stdlib.h> #include<set> #include<iterator> #include<iostream> using namespace std; #define ll long long #define inf 1000000007 #define MAXN 20010 ll z[MAXN]; int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n*2;i++) scanf("%lld",&z[i]); sort(z+1,z+n+n+1); ll ans=0; for(int i=1;i<=2*n;i=i+2) { if(z[i+1]>z[i]) ans=ans+z[i+1]-z[i]; else ans=ans+z[i]-z[i+1]; } printf("%lld\n",ans); } return 0; }View Code
2017年上海金馬五校程序設計競賽