很久很久没有写过CF的题解了。我可能也就在CF DIV3里面一展拳脚了。其他的也就签到一下,就没有然后。
认真想了想,其实这一套题都不难,但是为什么我只能做三题呢,很大程度就是卡题对我影响太大,而且自己做题,
没有队友的翻译,读题也是一个问题了。D题也就暴力,但是我真的没想到,我以前的想法都是沾边,但是要是我自己
想下去可能就可以沾到答案了。。。以致后面的E、F、G没读题,也没做。太吃力了英语题。。。我只能问问别人是什么意思
才会做下去,不然我一定做不了了。这是我第一次在CF上写的一次全题解。
A:问题是 给你N 个元素,去重后 按照最后一个出现的位置排序,也就是从右往左出现的顺序。
这一题有一点取巧,但是不难想,就是和我们平时去重一样,但是这次是从右往左的顺序来标记 放进数组,
然后输出即可。代码是用Set来练手罢了,其实开一个vis数组也是挺不错的。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
int a[100005]={0};
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
set<int>S;
int b[1005],cnt=0;
for(int i=n-1;i>=0;i--){
if(S.count(a[i])==0){
S.insert(a[i]);
b[cnt++]=a[i];
}
}
printf("%d\n",cnt);
for(int i=cnt-1;i>=0;i--){
printf("%d%c",b[i],i==0?'\n':' ');
}
return 0;
}
B、比A题还水,它的问题直接要你找多少组 XXX连在一起 。
一个for循环解决:
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
int n;
scanf("%d",&n);
cin>>s;
int ans=0;
for(int i=2;i<s.size();i++){
if(s[i]=='x'&&s[i-1]=='x'&&s[i-2]=='x'){
ans++;
}
}
printf("%d\n",ans);
return 0;
}
C、题意:有N个宿舍楼,里面有a[1~n]个宿舍,然后它们都是连在一起的,就是说
一号楼最后一个房间和二号楼第一个房间的号码是相邻的。
问题是 给你一个数,要你判断是几号楼第几个房间,其实这个应该要用二分。但是这题好像数据用不上。
前缀和+二分
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll sum[200500],a[200500],b[200500];
ll n,m;
int low_bound(ll x){
int L=1,R=n,mid;
while(L<R){
mid=(L+R)/2;
if(sum[mid]>=x){
R=mid;
}else{
L=mid+1;
}
}
return L;
}
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
}for(int i=1;i<=m;i++){
scanf("%lld",&b[i]);
}
for(int i=1;i<=m;i++){
ll ans1,ans2;
ans1=lower_bound(sum+1,sum+n+1,b[i])-sum;
ans2=b[i]-sum[ans1-1];
printf("%lld %lld\n",ans1,ans2);
}
return 0;
}
D、给你一个数列,要你构造一个等差数列,你只能对 任一个数进行+1或者-1
问:如果能构造 请输出 最小的改变数,要是不能,请输出-1
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,b[100010];
while(~scanf("%d",&n)){
for(int i=0;i<n;i++){
scanf("%d",&b[i]);
}
if(n==1||n==2){printf("0\n");continue;}
int L=b[0],R=b[n-1];
int ans=0x3f3f3f3f,i,j,tL,tR;
for(i=-1;i<=1;i++){
for(j=-1;j<=1;j++){
int tmp=0;
if(i!=0)tmp++;
if(j!=0)tmp++;
tL=L+i;
tR=R+j;
//cout<<" TL :"<<tL<<" "<<" TR :"<<tR<<" "<<"i ,j: "<<i<<" "<<j<<endl;
if((tR-tL)%(n-1)!=0) continue;
int d=(tR-tL)/(n-1),k;
for(k=1;k<n-1;k++){
if(abs(b[k]-(tL+k*d))<=1){
if(b[k]-(tL+k*d)!=0){
tmp++;
//cout<<b[k]<<endl;
}
}else{
break;
}
}
// cout<<tmp<<endl;
if(k==n-1){
ans=min(tmp,ans);
}
}
}
if(ans==0x3f3f3f3f){
printf("-1\n");
}else{
printf("%d\n",ans);
}
}
return 0;
}
E、讲述了n个公交车站,有a[1~n]个数字,容量为W
<0 是下车
>0 是上车
=0 飞站。
问你最初 在车上有多少种情况。纯属猜题,看了错误示例。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,w,a[1060];
while(~scanf("%d%d",&n,&w)){
int sum[1050]={0};
int maxz=-1,minz=0x3f3f3f3f,flag=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
if(sum[i]>0&&flag==0){
flag=1;
}else if(sum[i]<0&&flag==0){
flag=-1;
}else if(flag!=0&&sum[i]*flag<0){
flag=2;
}
maxz=max(maxz,sum[i]);
minz=min(minz,sum[i]);
}
if(maxz==minz&&maxz==0){
printf("%d\n",w+1);
}else if(flag==2)
printf("%d\n",(w-(maxz-minz)+1)>0?w-(maxz-minz)+1:0);
else if(flag==1){
printf("%d\n",(w+1-maxz)>0?w+1-maxz:0);
}else if(flag==-1){
printf("%d\n",(w+1+minz)>0?w+1+minz:0);
}
}
return 0;
}
F、题意:有n个人, 每一个人有一个能力值, 然后求这个能力值高的人能当能力值低的人的导师,
然后又m对人在吵架, 如果2个人吵架, 他们2个人就不能组成导师关系,
现在求每个人可以当多少个人的导师数目。
看代码实现,排序+lowerbound
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
int x,num,No;
}node;
int cmp1(node a,node b){
if(a.x==b.x){
return a.No<b.No;
}
return a.x<b.x;
}
int cmp2(node a,node b){
return a.No<b.No;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
node a[200050];
int b[200050]={0};
for(int i=0;i<n;i++){
scanf("%d",&a[i].x);
b[i]=a[i].x;
a[i].num=0;
a[i].No=i;
}
int u,v;
while(m--){
scanf("%d%d",&u,&v);
if(a[u-1].x>a[v-1].x){
a[u-1].num--;
}else if(a[u-1].x<a[v-1].x){
a[v-1].num--;
}
}
sort(a,a+n,cmp1);
sort(b,b+n);
for(int i=0;i<n;i++){
a[i].num+=(lower_bound(b,b+n,a[i].x)-b);
}
sort(a,a+n,cmp2);
for(int i=0;i<n;i++){
printf("%d%c",a[i].num,i==n-1?'\n':' ');
}
}
return 0;
}
G题:贪心加模拟
给你N天,M门科目。
m门科目有 s d c- s知道这门学科考试时间, d-考试时间,c复习时间。
问你每一天怎么复习,要是不行就输出-1。
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
int s,d,c,id;
}node;
node a[1000];
int n,m;
int cmp(node a,node b){
return a.d<b.d;
}
int main()
{
while(~scanf("%d%d",&n,&m)){
int data[10005]={0};
int flag=1;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a[i].s,&a[i].d,&a[i].c);
a[i].id=i;
if(data[a[i].d]==m+1){
flag=0;
}else{
data[a[i].d]=m+1;
}
}
sort(a+1,a+1+m,cmp);
int cur=1;
for(int i=1;i<=n;i++){
if(data[i]==m+1){
continue;
}
else if(i<a[cur].s&&data[i]==0){
for(int j=cur;j<n;j++){
if(i>=a[j].s&&a[j].c&&i<a[j].d){
data[i]=a[j].id;
a[j].c--;
break;
}
}
continue;
}else if(a[cur].s<=i&&a[cur].c&&data[i]==0&&i<a[cur].d){
data[i]=a[cur].id;
a[cur].c--;
}else if(a[cur].s<=i&&a[cur].c&&data[i]){
flag=0;break;
}
if(a[cur].c==0){
cur++;
}
if(cur==m+1){
break;
}
}
for(int i=1;i<=m;i++){
if(a[i].c){
flag=0;
}
}
/*for(int i=1;i<=n;i++){
printf("%d%c",data[i],i==n?'\n':' ');
}*/
if(flag){
for(int i=1;i<=n;i++){
printf("%d%c",data[i],i==n?'\n':' ');
}
}else{
printf("-1\n");
}
}
return 0;
}