[模拟赛]11.5

名字排序(name)

【问题描述】
给定 n 个字符串,请去重后按照字典序排序
【输入格式】 从文件 name.in中读入数据。 输入的第一行包含两个正整数 n 表示总数
,接下来 n行有 n 个字符串。
【输出格式】
第一行输出去重后的字符串个数 X
接下来 x 行按照字典序输出每一个字符串
【样例 1 输入】
4
a
ab
cdef
ejdeh
【样例 1 输出】
4
a
ab
cdef
ejdeh
对于 20%的数据保证不需要去重
对于 100%的数据 n<=100000;单个字符串长度小于 10

//大水题,但学到了知识

string可以用sort排序,得到的是字典序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;

const int maxn = 100000 + 100;
string ch[maxn];
int n,ans = 0;

int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; i++)	cin>>ch[i];
    sort(ch+1,ch+1+n);
    for(int i = 1; i <= n; i++)
        if(ch[i] != ch[i-1]) ans++;
    cout<<ans<<endl;
    for(int i = 1; i <= n; i++) {
        if(ch[i] == ch[i-1]) continue;
        cout<<ch[i]<<endl;
    }
    return 0;
}

对于 100%的数据 n<=100000;单个字符串长度小于 10
大吉大利(jiry)
【问题描述】
“大吉大利,晚上吃鸡!”
牛牛最近迷上了《绝地求生 大逃杀》这款游戏。他恨不能每天都吃鸡。但是他的舍友还
在王者峡谷等着他开黑。然而牛牛的心中只有一件事,那就是学习。
现在共有 n 天,每天都有一个数字 i,具体含义如下:
0 牛牛不能吃鸡也不能玩农药
1 牛牛可以吃鸡但不能玩农药
2 牛牛不可以吃鸡但可以玩农药
3 牛牛可以吃鸡或者玩农药
每天只能选择吃鸡、玩农药、学习中的一件事,并且牛牛不能连续两天吃鸡也不能连续两
天玩农药。请求出牛牛最大的学习的总天数。
【输入格式】 从文件 jiry.in中读入数据。 输入的第一行包含两个正整数 n 表示总天数。
接下来 n 行,每行包含 1个数字 i
【输出格式】输出到文件 jiry.out 中。输出一个牛牛最多学习的总天数。
【样例 1 输入】

7
1 3 3 2 1 2 3
【样例 1 输出】
0
【样例 2 输入】
2
2 2
【样例 2 输出】
1
【样例 3 输入】
4
1 3 2 0
【样例 3 输出】
2

//改编题,来自cf698A
//DP,贪心都行

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 233;
int n,f[maxn][10];   // 0 study 1 wangzhe 2 ji

int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + ch - '0';
        ch = getchar();
    }
    return x * f;
}

int main() {
    n = read();
    for(int i = 0; i <= n; i++) {
        for(int j = 0; j <= 2; j++) 
            f[i][j] = 1<<29;
    }
    f[0][0] = 0;
    for(int i = 1; i <= n; i++) {
        int a = read();
        if(a == 1 || a == 3) {
            f[i][2] = min(f[i - 1][1], f[i][2]);
            f[i][2] = min(f[i - 1][0], f[i][2]);	
        }
        if(a == 2 || a == 3) {
            f[i][1] = min(f[i - 1][2], f[i][1]);
            f[i][1] = min(f[i - 1][0], f[i][1]);
        }
        f[i][0] = min(f[i - 1][2] + 1,f[i][0]);
        f[i][0] = min(f[i - 1][0] + 1,f[i][0]);
        f[i][0] = min(f[i - 1][1] + 1,f[i][0]);
    }
    int ans = 1<<29;
    ans = min(ans,f[n][0]);
    ans = min(ans,f[n][1]);
    ans = min(ans,f[n][2]);
    cout<<ans<<endl;
    return 0;
}

电话线(line)
多年以后,笨笨长大了,成为了电话线布置师。由于地震使得某市的电话线全部损坏,笨笨
是负责接到震中市的负责人。该市周围分布着 N(1<=N<=1000)根据 1……n 顺序编号的废弃
的电话线杆,任意两根线杆之间没有电话线连接,一共有 p(1<=p<=10000)对电话杆可以拉
电话线。其他的由于地震使得无法连接。

第 i 对电线杆的两个端点分别是 ai,bi,它们的距离为 li(1<=li<=1000000)。数据中每对
(ai,bi)只出现一次。编号为 1的电话杆已经接入了全国的电话网络,整个市的电话线全都
连到了编号 N 的电话线杆上。也就是说,笨笨的任务仅仅是找一条将 1 号和 N 号电线杆连起
来的路径,其余的电话杆并不一定要连入电话网络。
电信公司决定支援灾区免费为此市连接 k 对由笨笨指定的电话线杆,对于此外的那些电话
线,需要为它们付费,总费用决定于其中最长的电话线的长度(每根电话线仅连接一对电话
线杆)。如果需要连接的电话线杆不超过 k 对,那么支出为 0.
请你计算一下,将电话线引导震中市最少需要在电话线上花多少钱?
输入输出格式
输入格式:
输入文件的第一行包含三个数字 n,p,k;
第二行到第 p+1行,每行分别都为三个整数 ai,bi,li。
输出格式:
一个整数,表示该项工程的最小支出,如果不可能完成则输出-1.
输入输出样例
输入样例#1:
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
输出样例#1:
4

//usaco原题

二分 + spfa

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxb = 10000 + 233;
const int maxd = 1000 + 233;
int n,p,k;
struct edge {
    int u,v,w,next;
}e[maxb<<1];
int head[maxd],tot = 0;
struct node {
    int u,v,w;
    bool operator < (const node a) const {
        return w < a.w;
    }
}d[maxb];

int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + ch - '0';
        ch = getchar();
    }
    return x * f;
}

void add(int u, int v, int w) {
    e[++tot] = (edge){u,v,w,head[u]};
    head[u] = tot;
}

int dis[maxd],vis[maxd],du[maxd];

bool spfa(int mid) {
    for(int i = 1; i <= n; i++) dis[i] = 1<<29;
    memset(vis,0,sizeof(vis));
    vis[1] = 1, dis[1] = 0;
    queue<int>q;
    q.push(1);
    while(!q.empty()) {
        int k = q.front(); q.pop();
        vis[k] = 0;
        for(int i = head[k]; i; i = e[i].next) {
            int v = e[i].v;
            if(e[i].w <= mid && dis[v] > dis[k]) {
                dis[v] = dis[k];
                if(!vis[v]) {
                    du[v] = i;
                    vis[v] = 1;
                    q.push(v);
                }
            }
            if(e[i].w > mid && dis[v] > dis[k] + 1) {
                dis[v] = dis[k] + 1;
                if(!vis[v]) {
                    du[v] = i;
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
    return dis[n] <= k;
}

int main() {
    n = read(), p = read(), k = read();
    for(int i = 1; i <= p; i++) {
        d[i].u = read(), d[i].v = read(), d[i].w = read();
        add(d[i].u,d[i].v,d[i].w);
        add(d[i].v,d[i].u,d[i].w);
    }
    int r = 0, l = 1000000, ans = -1;
    while(r <= l) {
        int mid = (l + r) >> 1;
        if(spfa(mid)) {
            ans = mid;
            l = mid - 1;
        }
        else r = mid + 1;
    }
    cout<<ans<<endl;
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值