A:链接:http://codeforces.com/contest/479/problem/A
分析:把所有可能都尝试一遍就可以了。。。。
代码:
#include <iostream> #include <algorithm> #include <string.h> #include <iomanip> #include <map> #include <vector> #include <math.h> #include <string> using namespace std; typedef long long ll; const int mod = 1e9+7; const int N=100020; int ans[N]; ll arr[N]; int n,m,k,a,r,g,b,c; string s1,s2; int main() { while(cin>>a>>b>>c) { int ans = 0; ans = max(ans,a+b+c); ans = max(ans,a*b*c); ans = max(ans,a+b*c); ans = max(ans,(a+b)*c); ans = max(ans,a*b+c); ans = max(ans,a*(b+c)); cout<<ans<<endl; } return 0; }
B题,链接:http://codeforces.com/contest/479/problem/B
分析:因为数据不大,故可以每次都排序,然后将最大的减一,最小的加一,知道最大的和最小的相差不过1
代码:
#include <iostream> #include <algorithm> #include <string.h> #include <iomanip> #include <map> #include <vector> #include <math.h> #include <string> using namespace std; typedef long long ll; const int mod = 1e9+7; const int N=100020; int ans[N]; ll arr[N]; int n,m,k,a,r,g,b,c; string s1,s2; int main() { while(cin>>n>>m) { vector<pair<int,int> > v; for(int i=1;i<=n;i++) { cin>>a; v.push_back(make_pair(a,i)); } int cnt = 0; vector<pair<int,int> > ans; while(cnt<m) { sort(v.begin(),v.end()); int diff = v[v.size()-1].first-v[0].first; if(diff==0||diff==1) { break; } else { ans.push_back(make_pair(v[v.size()-1].second,v[0].second)); v[v.size()-1].first--; v[0].first++; cnt++; } } sort(v.begin(),v.end()); int diff = v[v.size()-1].first-v[0].first; cout<<diff<<" "<<ans.size()<<endl; for(int i=0;i<ans.size();i++) cout<<ans[i].first<<" "<<ans[i].second<<endl; } return 0; }
c题,链接:http://codeforces.com/contest/479/problem/c
分析:题目读了半天,感觉题目写的有点问题。。。。意思是不管你选哪天来考试,它都会记录ai来当作record,这样便可以根据ai来排序,然后每次能选bi就选bi,不行就选ai
代码:
#include <iostream> #include <algorithm> #include <string.h> #include <iomanip> #include <map> #include <vector> #include <math.h> #include <string> using namespace std; typedef long long ll; const int mod = 1e9+7; const int N=100020; int ans[N]; ll arr[N]; int n,m,k,a,r,g,b,c; string s1,s2; int main() { while(cin>>n) { vector<pair<int,int> > v; for(int i=0;i<n;i++) { cin>>a>>b; v.push_back(make_pair(a,b)); } sort(v.begin(),v.end()); int ans = 0; for(int i=0;i<v.size();i++) { if(i==0) ans = v[i].second; else { if(v[i].second>=v[i-1].second) { if(v[i].second>=ans) ans = v[i].second; else ans = v[i].first; } else ans = v[i].first; } } cout<<ans<<endl; } return 0; }
D题:链接:http://codeforces.com/contest/479/problem/D
分析:因为0和l是肯定有的,所以答案不会超过2个,故可以先判断x和y是否都能被检测出来,如果两个都可以的话,返回0,只有一个可以的话,那么直接返回那一个,反正总是要加一个的,而若是两个都没有的话,则看能不能通过加一个的方法来满足测两个的要求,不行的话就返回x,y两个。
代码:
#include <iostream> #include <algorithm> #include <string.h> #include <iomanip> #include <map> #include <vector> #include <math.h> #include <string> #include <set> using namespace std; typedef long long ll; const int mod = 1e9+7; const int N=100020; int ans[N]; int arr[N]; int n,m,k,a,r,g,b,c,l,x,y; string s1,s2; set<int> s; int canFind(int x) { for(int i=0;i<n;i++) { if(s.count(arr[i]-x)) return 1; } return 0; } int find() { for(int i=0;i<n;i++) { if(arr[i]+x>=0&&arr[i]+x<=l&&s.count(arr[i]+x+y)>0) return arr[i]+x; if(arr[i]-x>=0&&arr[i]-x<=l&&s.count(arr[i]-x+y)>0) return arr[i]-x; if(arr[i]+x>=0&&arr[i]+x<=l&&s.count(arr[i]+x-y)>0) return arr[i]+x; if(arr[i]-x>=0&&arr[i]-x<=l&&s.count(arr[i]-x-y)>0) return arr[i]-x; } return -1; } int main() { while(cin>>n>>l>>x>>y) { s.clear(); for(int i=0;i<n;i++) { cin>>arr[i]; s.insert(arr[i]); } int t1 = canFind(x); int t2 = canFind(y); if(t1&&t2) cout<<0<<endl; else if(t1&&!t2) cout<<1<<endl<<y<<endl; else if(!t1&&t2) cout<<1<<endl<<x<<endl; else { int p = find(); if(p==-1) { cout<<2<<endl; cout<<x<<" "<<y<<endl; } else { cout<<1<<endl; cout<<p<<endl; } } } return 0; }
E题,链接:http://codeforces.com/contest/479/problem/E
分析:很显然是个dp问题,但是我只能想到dp[k][i][j]来表示第k次走到i这个位置,来源是j,这样的话是肯定可以算的,但是由于N=5000,肯定会超时。。。但是观察其实可以发现,若当前位置为i,则可以走到i这个位置的点其实是一条连续的线段,而在计算i这个点的时候,我们需要的是这条线段的和,故可以利用前缀和的方法,每次用O(1)的时间来计算出线段和,从而整个算法的复杂度为O(KN),同时需要注意的是,若a<b,则永远不可能跑到b上面去,反之则永远不可能跑到b下面去,这点在计算线段的位置比较有用
代码:
#include <iostream> #include <algorithm> #include <string.h> #include <iomanip> #include <map> #include <vector> #include <math.h> #include <string> #include <set> using namespace std; typedef long long ll; const int mod = 1e9+7; const int N=100020; ll dp[2][N]; ll f[N]; int ans[N]; int arr[N]; int n,m,k,a,r,g,b,c,l,x,y; string s1,s2; int main() { while(cin>>n>>a>>b>>k) { memset(dp,0,sizeof(dp)); memset(f,0,sizeof(f)); dp[0][a]=1; int now = 0; int pre = 1; for(int i=1;i<=k;i++) { now^=1; pre^=1; for(int j=1;j<=n;j++) { f[j] = f[j-1]+dp[pre][j]; } for(int j=1;j<=n;j++) { int l,r; if(j < b) l=1, r=(b+j+1)/2-1; else if(j>b) l=(b+j)/2+1, r=n; else continue; dp[now][j] = (f[r]-f[l-1]-dp[pre][j]+mod)%mod; } } ll ans = 0; for(int j=1;j<=n;j++) ans = (ans+dp[now][j])%mod; cout<<ans<<endl; } return 0; }