A;
这题比较简单就直接上代码了:
#include <bits/stdc++.h> #define ed end() #define bg begin() #define mkp make_pair #define pb push_back #define v(T) vector<T> #define all(x) x.bg,x.ed #define newline puts("") #define si(x) ((int)x.size()) #define rep(i,n) for(int i=1;i<=n;++i) #define rrep(i,n) for(int i=0;i<n;++i) #define srep(i,s,t) for(int i=s;i<=t;++i) using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn = 1e5+10; const int inf = 0x7f7f7f7f; const ll inf_ll = 1ll*inf*inf; const int Mod = 1e9+7; const double eps = 1e-7; string s; int cnt=0; int main(){ while(getline(cin,s)){ cnt=0; string ans=""; for (int i=0;i<s.length();i++){ if(s[i]>='0' && s[i]<='9'){ ans+=s[i]; } else{ if(ans.size() == 0) continue; int j=0; if(ans.size()==1) { cout<<ans<<" "; ans=""; continue; } int zero=0; for (int j=0;j<ans.size();j++){ if(ans[j]=='0') zero++; } if(zero == ans.size()){ cout<<"0 "; ans="";continue; } for ( j=0;j<ans.size();j++){ if(ans[j]!='0') break; } for (int k=j;k<ans.size();k++){ cout<<ans[k]; } cout<<" "; ans = ""; } } if(ans[0]>='0' && ans[0]<='9'){ if(ans.size()==1) { cout<<ans<<" "; ans=""; newline; continue; } int zero=0; for (int j=0;j<ans.size();j++){ if(ans[j]=='0') zero++; } if(zero == ans.size()){ cout<<"0 "; ans="";continue; } int j=0; for ( j=0;j<ans.size();j++){ if(ans[j]!='0') break; } for (int k=j;k<ans.size();k++){ cout<<ans[k]; } newline; } else newline; } return 0; }
B:
思路:只要知道&的性质就行了,对于一个数的二进制来说0&0=0,0&1=0,所以&起来最大就是数据的最大值。
#include <bits/stdc++.h> using namespace std; int main(){ int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); int temp=0; for(int i=0;i<n;i++){ int x; scanf("%d",&x); if(x>temp)temp=x; } printf("%d\n",temp); } return 0; }
C:
思路:打表找了找规律,发现有规律,就直接交了,规律见代码:
代码:
#include <bits/stdc++.h> using namespace std; int main(){ int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); if(n%3==0)printf("Frame\n"); else printf("Alan\n"); } return 0; }
D:
思路:对序列上的每一位考虑使用单点修改或者前缀修改或者不修改所造成的影响,从而推出递推公式,代码不长,递推公式见代码。
代码:
#include <bits/stdc++.h> using namespace std; int dp[100005][2],a[100005]; int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++)scanf("%d",&a[i]); if(a[0]==1)dp[0][0]=1,dp[0][1]=0; else dp[0][1]=1; for(int i=1;i<n;i++){ if(a[i]==0){ dp[i][0]=min(dp[i-1][0],dp[i-1][1]+1); dp[i][1]=min(dp[i-1][1]+1,dp[i-1][0]+1); } else{ dp[i][0]=min(dp[i-1][0]+1,dp[i-1][1]+1); dp[i][1]=dp[i-1][1]; dp[i][1]=min(dp[i][1],dp[i-1][0]+2); } //printf("%d %d %d\n",i,dp[i][0],dp[i][1]); } printf("%d\n",dp[n-1][0]); return 0; }
E:
思路:这题难点就在于如何建图,观察题目可以发现,两点之间的权值是他们的lowbit,所以图的权值应该是该值的二进制位,所以我们增加32个点,如果点值得二进制在这位为1,我们就建立一条边,这样两点之间得权值就是他们的最短路了。
代码:
#include <bits/stdc++.h> using namespace std; long long a[100005]; bool vis[100105]; #define inf 0x3f3f3f3f3f3f struct Node{ int v; long long w; Node(int vv,long long ww):v(vv),w(ww){} }; vector<Node>edge[100105]; void addedge(int u,int v,long long w) { edge[u].push_back(Node(v,w)); } long long dist[101005]; void bfs() { memset(dist,inf,sizeof(dist)); dist[1]=0; priority_queue<pair<long long,int>,vector<pair<long long ,int > >,greater<pair<long long,int> > >q; q.push(make_pair(dist[1],1)); while(!q.empty()){ int u=q.top().second; q.pop();//printf("%d\n",u); if(vis[u])continue; vis[u]=true; for(int i=0;i<edge[u].size();i++){ int v=edge[u][i].v; long long w=edge[u][i].w; if(!vis[v]&&dist[v]>dist[u]+w){ dist[v]=dist[u]+w; q.push(make_pair(dist[v],v)); } } } } void init(int n) { for(int i=0;i<n+100;i++){ edge[i].clear(); } } int main(){ int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); init(n); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); } memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++){ int cnt=1;//printf("123"); long long temp=1; while(a[i]){ if(a[i]%2){ addedge(i,n+cnt,temp); addedge(n+cnt,i,temp); //printf("aaa%d %d\n",i,n+cnt); } temp*=2; a[i]/=2; cnt++; } } bfs(); if(dist[n]/2==2278715444399415199)printf("Impossible\n"); else printf("%lld\n",dist[n]/2); } return 0; }