**A:第几天
B:加油站
C:序列求平均
D:士兵排阵
**
http://39.106.164.46/problem.php?id=1015
思路:
分闰年和非闰年讨论即可。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 100005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
string s;
map<int,int> mp;
int main(){
mp[1]=31,mp[2]=28,mp[3]=31,mp[4]=30,mp[5]=31;
mp[6]=30,mp[7]=31,mp[8]=31,mp[9]=30,mp[10]=31;
mp[11]=30,mp[12]=31;
while(cin>>s){
int y=0,m=0,d=0,cnt=0,tmp=0;
for(int i=0;i<s.length();i++){
if(s[i]>='0'&&s[i]<='9') tmp=tmp*10+s[i]-'0';
else{
if(cnt==0){
cnt++;
y=tmp;
tmp=0;
}else if(cnt==1){
cnt++;
m=tmp;
tmp=0;
}
}
}
d=tmp;
bool flag=false;
if(y%400==0) flag=true;
if(y%4==0&&y%100!=0) flag=true;
if(flag==true){
mp[2]=29;
}
int ans=0;
for(int i=1;i<m;i++){
ans+=mp[i];
}
ans+=d;
mp[2]=28;
printf("%d\n",ans);
}
return 0;
}
http://39.106.164.46/problem.php?id=1016
思路:
贪心模板题。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 5005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,k,dis[MAX];
int main(){
while(cin>>n>>k){
int sum=0;
for(int i=1;i<=k+1;i++){
cin>>dis[i];
sum+=dis[i];
}
int cnt=0,now=0,id=1;
if(n<dis[1]){printf("NoSolution\n");continue;}
bool flag=true;
while(now<sum){
int tmp=0;
if(n<dis[id]&&now<sum){
flag=false;
break;
}
while(tmp+dis[id]<=n){
tmp+=dis[id++];
}
now+=tmp;
cnt++;
}
if(flag) printf("%d\n",cnt-1);
else printf("NoSolution\n");
}
return 0;
}
http://39.106.164.46/problem.php?id=1017
思路:
vector模拟一下即可。
AC代码:
#include
#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;
int main(){
while(cin>>n>>m){
vector<int> vec,res;
for(int i=1;i<=n;i++) vec.push_back(i*2);
int cnt=0,tmp=0;
for(int i=0;i<vec.size();i++){
tmp+=vec[i];
cnt++;
if(cnt==m){
res.push_back(tmp/m);
cnt=0;
tmp=0;
}
}
if(cnt!=0) res.push_back(tmp/cnt);
for(int i=0;i<res.size();i++){
printf("%d ",res[i]);
}
printf("\n");
}
return 0;
}
http://39.106.164.46/problem.php?id=1018
思路:
假设每个点的坐标为(X1, Y1), (X2, Y2), …, (Xn-1, Yn-1), (Xn, Yn)。在x方向和y方向上将坐标分别排序,对于Y方向,假设最终所有士兵的坐标为Y,即求|Y1-Y| + |Y2-Y| + … + |Yn-1-Y| + |Yn-Y|的最小值,可以证明Y其实是Y1,Y2…Yn的中位数。对于x方向,假设最后所有士兵的位置为(X, X+1, X+2, …, X+n-1),通过上面的解释,我们令X1->X, X2->X+1, …, Xn-1->X+n-2, Xn->X+n-1,这样不会产生碰撞。那么我们求的就是|X1-X| + |X2-(X+1)| + … + |Xn-1-(X+n-2)| + |Xn-(X+n-1)|的最小值,将该式变换,得|X1-X| + |(X2-1)-X| + … + |[Xn-1-(n-2)]-X| + |[Xn-(n-1)]-X|的最小值,要使该式子最小,即X为X1, X2-1, …, Xn-1-(n-2), Xn-(n-1)的中位数,于是可以把X[i]都减去(i-1),找出中位数,计算最小步数。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 10005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,x[MAX],y[MAX];
int main(){
while(cin>>n){
for(int i=0;i<n;i++){
cin>>x[i]>>y[i];
}
sort(x,x+n);
for(int i=0;i<n;i++) x[i]-=i;
sort(x,x+n);
sort(y,y+n);
int midx=x[n/2],midy=y[n/2];
int cnt=0;
for(int i=0;i<n;i++){
cnt+=abs(x[i]-midx);
cnt+=abs(y[i]-midy);
}
cout<<cnt<<endl;
}
return 0;
}
http://39.106.164.46/problem.php?id=1019
思路:
区间dp。可以参考:
https://blog.csdn.net/weixin_44123362/article/details/102704895
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 305
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,a[MAX],sum[MAX],dp[MAX][MAX];
int d(int i,int j){ //计算合并i~j的代价
return sum[j]-sum[i-1];
}
int main(){
while(cin>>n){
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
for(int l=1;l<n;l++){
for(int i=1,j=i+l;i<=n&&j<=n;i++,j=i+l){
dp[i][j]=INF;
for(int k=i;k<j;k++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+d(i,j));
}
}
}
cout<<dp[1][n]<<endl;
}
return 0;
}