http://39.106.164.46/problem.php?id=1252
思路:
使用map即可。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,flag[10];
string s[MAX];
map<string,int> mp;
int main(){
mp["red"]=0;mp["orange"]=1;mp["yellow"]=2;
mp["green"]=3;mp["cyan"]=4;mp["blue"]=5;mp["purple"]=6;
while(cin>>n){
memset(flag,0,sizeof(flag));
for(int i=0;i<n;i++){
cin>>s[i];
flag[mp[s[i]]]=1;
}
int cnt=0;
for(int i=0;i<7;i++){
if(flag[i]==0) cnt++;
}
cout<<cnt<<endl;
for(int i=0;i<7;i++){
if(flag[i]==0){
if(i==0) cout<<"A"<<endl;
else if(i==1) cout<<"B"<<endl;
else if(i==2) cout<<"C"<<endl;
else if(i==3) cout<<"D"<<endl;
else if(i==4) cout<<"E"<<endl;
else if(i==5) cout<<"F"<<endl;
else if(i==6) cout<<"G"<<endl;
}
}
}
return 0;
}
http://39.106.164.46/problem.php?id=1253
思路:
此题是比较两个数对间的“大小关系”。
也就是说,若交换前的价值大于交换后的价值,就需要a1-b1
a-b
大的排在前面即可。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n;
struct node{
int fir,sec;
bool operator < (const node &a) const{
return fir-sec>a.fir-a.sec;
}
node(int f,int s){
fir=f;
sec=s;
}
};
vector<node> vec;
int main(){
int f,s;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%d %d",&f,&s);
vec.push_back(node(f,s));
}
sort(vec.begin(),vec.end());
ll res=0;
for(int i=0;i<n;i++){
int j=i+1;
res+=ll(j-1)*vec[i].fir+ll(n-j)*vec[i].sec;
}
printf("%lld\n",res);
vec.clear();
}
return 0;
}
http://39.106.164.46/problem.php?id=1254
思路:
简单的dp。
每个格子可以由左边的格子或者右边的格子到达,那么很容易写出递推式:
dp[i][j] = (dp[i-1][j] + dp[i][j-1]) %mod
由于题目是从(x1,y1)到达(x2,y2),我们将(x1,y1)平移到左上角,(x2,y2)平移相同的距离,即dp[x2-(x1-1)][y2-(y1-1)]
就是最终答案。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 5005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m,q,dp[MAX][MAX];
int x1,x2,y_1,y2;
int mod=1e9+7;
int main(){
memset(dp,0,sizeof(dp));
for(int i=1;i<MAX;i++) dp[i][1]=1;
for(int j=1;j<MAX;j++) dp[1][j]=1;
for(int i=2;i<MAX;i++){
for(int j=2;j<MAX;j++){
dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mod;
}
}
while(scanf("%d %d %d",&n,&m,&q)!=EOF){
for(int i=0;i<q;i++){
scanf("%d %d %d %d",&x1,&y_1,&x2,&y2);
x2=x2-x1+1,y2=y2-y_1+1;
printf("%d\n",dp[x2][y2]);
}
}
return 0;
}
http://39.106.164.46/problem.php?id=1255
思路:
如果不考虑L的限制,我们需要让桶最短的那根木棍尽可能长,那么可以将木棍的长度从小到大排序,从大的往小的依次选择,当每有k根木棍时,就组成一个桶;如果考虑L的限制,由于所有木棍最短的那根一定决定了最小容量,因此,我们只要最大的桶的最短的那根木棍长度小于等于a[0]+l
即可。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 100005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,k,l,m,a[MAX];
int main(){
scanf("%d %d %d",&n,&k,&l);
m=n*k;
for(int i=0;i<m;i++){
scanf("%d",&a[i]);
}
sort(a,a+m);
int max_pos=upper_bound(a,a+m,a[0]+l)-a;
ll ans=0;
int cnt=0;
for(int i=m-1;i>=0;i--){
cnt++;
if(i<max_pos&&cnt>=k){
cnt-=k;
ans+=a[i];
}
}
if(cnt>0) printf("0\n"); //说明还有木棍没用上,那么就不能组成n个桶了
else printf("%lld\n", ans);
return 0;
}
http://39.106.164.46/problem.php?id=1256
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 1000005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,c,a[MAX];
ll dp[MAX];
int main(){
ll sum=0;
multiset<int> s; //可重集
scanf("%d %d",&n,&c);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
for(int i=1;i<=n;i++){
dp[i]=dp[i-1];
s.insert(a[i]);
if(i>c) s.erase(s.find(a[i-c]));
if(i>=c) dp[i]=max(dp[i],dp[i-c]+(*s.begin()));
}
printf("%lld",sum-dp[n]);
return 0;
}