今天小练了一套题~这一套题好像都是思维题
A Exam
n个学生排成一排编号1,2,3....n,那么会发现第i个学生编号 与 第i+1个学生编号相邻,这样不满足要求。题目要求任意相邻的两学生编号差值的绝对值不为1;
思路:
把 编号为奇数的抽出来为一组 1,3,5,7,9....
把 编号为偶数的抽出来为一组 2,4,6,8,10...
然后两者都反向排列即可 ....9 7 5 3 1 .....10 8 6 4 2 注意判一下偶数组的最大值和奇数组的最小值的大小关系
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
int a[2550],b[2550];
int ct1,ct2;
int abs(int a)
{
return (a>0)?a:(-a);
}
int main()
{
int n;
while(cin>>n)
{
ct1=ct2=0;
for( int i=1; i<=n; i++)
{
if(i&1)
{
a[ct1++]=i;
}
else b[ct2++]=i;
}
if( abs(b[ ct2-1 ]-a[0])==1 )
{
printf("%d\n",ct1);
for(int i=ct1-1;i>=0;i--)
if(i==ct1-1)printf("%d",a[i]);
else printf(" %d",a[i]);
printf("\n");
}
else
{
printf("%d\n",ct1+ct2);
for(int i=ct1-1;i>=0;i--)
if(i==ct1-1)printf("%d",a[i]);
else printf(" %d",a[i]);
for(int i=ct2-1;i>=0;i--)
printf(" %d",b[i]);
printf("\n");
}
}
return 0;
}
B题 DP搞就行,dp[i][j]表示第i秒速度为j时的最大值,第i秒由第i-1秒推过来
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[110][5500];
int main()
{
int v1,v2,t,d;
while(cin>>v1>>v2>>t>>d)
{
memset(dp,0,sizeof(dp));
dp[1][v1]=1*v1;
for(int i=1;i<t;i++)
{
for(int v=1;v<=1200;v++)
{
if(dp[i][v]==0)continue;
for(int j=-d;j<=d;j++)
{
if(v+j<=0)continue;
dp[i+1][v+j]=max(dp[i+1][v+j],dp[i][v]+v+j);
}
}
}
printf("%d\n",dp[t][v2]);
}
return 0;
}
C题 思维题 稍微计算一下 每个骰子取值范围就行
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6+100;
ll d[maxn];
ll ans[maxn];
int main()
{
int n;
ll s;
while(scanf("%d%I64d",&n,&s)!=EOF)
{
ll sum=0;
for(int i=1;i<=n;i++)
{
scanf("%I64d",&d[i]);
sum+=d[i];
}
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++)
{
ll tmp=sum-d[i];
ll left=s-tmp;
ll right=s-n+1;
if( left>1&&left<=d[i] )ans[i]+=left-1;
if(right<=0)ans[i]+=d[i];
else if(right<d[i])ans[i]+=d[i]-right;
}
for(int i=1;i<=n;i++)
if(i==1)printf("%I64d",ans[i]);
else printf(" %I64d",ans[i]);
printf("\n");
}
return 0;
}
.D题 贪心处理即可 用vector比较方便些。
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=1e5+100;
vector<int>vec[2*maxn];
vector<int>ans;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<2*maxn-10;i++)vec[i].clear();
ans.clear();
for(int i=1;i<=n;i++)
{
int tmp;
scanf("%d",&tmp);
vec[tmp].push_back(i);
}
int sum=0,flag=0;
if( vec[0].empty() )
{
printf("Impossible\n");
continue;
}
ans.push_back(vec[0].back());
vec[0].pop_back();
sum++;
flag++;
for( int i=2;i<=n;i++ )
{
if(!vec[sum].empty())
{
ans.push_back(vec[sum].back());
vec[sum].pop_back();
flag++;
sum++;
}
else if(sum>=3)
{
while(sum>=3)
{
sum-=3;
if(!vec[sum].empty())
{
ans.push_back(vec[sum].back());
vec[sum].pop_back();
flag++;
sum++;
break;
}
}
}
else
break;
}
if(flag!=n)
{
printf("Impossible\n");
}
else
{
printf("Possible\n");
for(int i=0;i<ans.size();i++)
if(i==0)printf("%d",ans[i]);
else printf(" %d",ans[i]);
printf("\n");
}
}
return 0;
}