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;
}