中南大学第十三届程序设计竞赛题解

向右看

题解:

使用优先队列即可,身高小的优先,从左到右每当有人进入队列时,所有低于这个人身高的人看向的人就是这个人,把这些人出队列,记录下来就可以了。

代码如下:

#include<stdio.h>
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<queue>
#define MAX 100005
#define INF 0x3f3f3f3f
using namespace std;

struct node{
   int val;
   int id;
}t[MAX];

struct cmp{
    bool operator()(node a,node b){
        return a.val>b.val;
    }
};

priority_queue<node,vector<node>,cmp > q;
int res[MAX];
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&t[i].val);
        t[i].id=i;
    }
    for(int i=1;i<=n;i++){
        q.push(t[i]);
        if(!q.empty()){
            while(q.top().val<t[i].val){
                int id=q.top().id;
                q.pop();
                res[id]=i;
            }
        }
    }
    for(int i=1;i<=n;i++){
        printf("%d\n",res[i]);
    }
    return 0;
}

How many LOL?

题解:

数位dp,将字符串看成26进制的数,然后dfs+记忆化搜索。
时间复杂度:O(n * 26 * 26)

#include<stdio.h>
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<queue>
#include<string.h>
#define MAX 1005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

ll mod=1e9+7,num=26*26*26;
ll dp[MAX][30][30];
int n,t;

ll dfs(int pos,int c1,int c2){
    if(pos==0) return 1;
    if(dp[pos][c1][c2]!=-1) return dp[pos][c1][c2];
    ll ans=0;
    for(int i=1;i<=26;i++){
        if(c1=='L'-'A'+1&&c2=='O'-'A'+1&&i=='L'-'A'+1) continue;
        ans=(ans+dfs(pos-1,c2,i))%mod;
    }
    dp[pos][c1][c2]=ans;
    return ans;
}

ll f(ll x){
    int pos=x;
    return dfs(pos,0,0);
}

int main(){
    memset(dp,-1,sizeof(dp));
    while(scanf("%d",&t)!=EOF){
        while(t--){
            scanf("%d",&n);
            printf("%lld\n",f(n));
        }
    }
    return 0;
}

疯狂的企鹅

题解:

思路是贪心+排序。选取中位数是最好的选择方案。
我们可以选取行的中位数,把企鹅都移动到这一行,或者选取列的中位数,把企鹅都移动到这一列。

#include <iostream>
#include <stdio.h>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <cmath>
#include <algorithm>
#include <cstring>
#define MAX 600005
typedef long long ll;
using namespace std;

int x[MAX], y[MAX];

int main(){
    int n;
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        scanf("%d%d",&x[i],&y[i]);
    }
    sort(x+1,x+n+1);
    sort(y+1,y+n+1);
    ll ansx1=0,ansy1=0,ansx=0,ansy=0;
    ll mid=n/2+1;
    //如果移动到同一行
    for(int i=1;i<=n;i++){
        ansy+=abs(y[i]-y[mid]);
    }
    //如果移动到同一列
    for(int i=1;i<=n;i++){
        ansx+=abs(x[i]-x[mid]);
    }
    for(int i=1;i<=n;i++){ //转移需要的步数
        ansx1+=abs(i-x[i]);
        ansy1+=abs(i-y[i]);
    }
    ll ans=min(ansx1+ansy,ansy1+ansx);
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zzh1582188532/p/12354276.html
今日推荐