学习总结11

# 修复公路

## 题目背景

A 地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。

## 题目描述

给出 A 地区的村庄数 N,和公路数 M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)。

## 输入格式

第 1 行两个正整数 N,M。

下面 M 行,每行 3 个正整数 x,y,t,告诉你这条公路连着 x,y 两个村庄,在时间t时能修复完成这条公路。

## 输出格式

如果全部公路修复完毕仍然存在两个村庄无法通车,则输出 -1,否则输出最早什么时候任意两个村庄能够通车。

## 样例 #1

### 样例输入 #1

```
4 4
1 2 6
1 3 4
1 4 5
4 2 3
```

### 样例输出 #1

```
5
```

## 提示

1<= x, y<= N <= 10 ^ 3,1<= M, t <= 10 ^ 5。

解题思路

查并集的基本应用,用结构体数组来保存数据,另开一个模拟树用来模拟数组。用sort函数将数据根据时间进行排序然后遍历。将有关的村庄链接起来,每链接一个村庄就把村庄数减一。

代码

#include 
using namespace std;
struct ss
{
    int x;
    int y;
    int t;
}g[100001];
int j[100001];
int findm(int x)
{
    if(j[x]==x)
        return x;
    return findm(j[x]);
}
void jie(int x,int y)
{
    x=findm(x);
    y=findm(y);
    j[x]=y;
}
int bi(struct ss x,struct ss y)
{
    return x.t

# 最大子段和

## 题目描述

给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。

## 输入格式

第一行是一个整数,表示序列的长度 n。

第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字 ai。

## 输出格式

输出一行一个整数表示答案。

## 样例 #1

### 样例输入 #1

```
7
2 -4 3 -1 2 -4 3
```

### 样例输出 #1

```
4
```

## 提示

#### 样例 1 解释

选取 [3, 5] 子段 {3, -1, 2},其和为 4。

#### 数据规模与约定

- 对于 40% 的数据,保证 n <= 2 * 10^3。
- 对于 100% 的数据,保证 1 <= n <= 2 * 10^5,-10^4 <= ai <= 10^4。

解题思路

要用到前缀和来保存数据,用一个变量来保存子段和但要注意的是最大子段和可能是负数

代码

#include 
using namespace std;
long long a[200001];
int main()
{
    long long n,x,sum,max1;
    scanf("%lld",&n);
    for(x=1;x<=n;x++)
    {
        scanf("%lld",&a[x]);
    }
    sum=a[1];
    max1=sum;
    for(x=2;x<=n;x++)
    {
        if(a[x]+sum>=0)
        {
            sum+=a[x];
            if(max1max1)
                max1=a[x];
            sum=a[x];
        }
    }
    printf("%lld",max1);
    return 0;
}

# Spreadsheets

## 题面翻译

人们常用的电子表格软件(比如: Excel)采用如下所述的坐标系统:

第一列被标为 A,第二列为 B,以此类推,第 26 列为 Z。接下来为由两个字母构成的列号: 第 27 列为 AA,第 28 列为 AB …… 在标为 ZZ 的列之后则由三个字母构成列号,如此类推。

行号为从 1 开始的整数。

单元格的坐标由列号和行号连接而成。比如,BC23 表示位于第 55 列 23 行的单元格。

有时也会采用被称为 RXCY 的坐标系统,其中 X 与 Y 为整数,坐标 (X,Y) 直接描述了对应单元格的位置。比如,R23C55 即为前面所述的单元格。

您的任务是编写一个程序,将所给的单元格坐标转换为另一种坐标系统下面的形式。

## 输入

第一行一个整数 n (1 <= n <= 10^5) 表示将会输入的坐标的数量。

接下来 n 行,每行一个坐标。

注意: 每个坐标都是正确的。此外不会出现行号或列号大于 10^6 的单元格。

输出 n 行,每行一个被转换的坐标。

## 输出
n 行,每行一个被转换的坐标。

## 样例 #1

### 样例输入 #1

```
2
R23C55
BC23
```

### 样例输出 #1

```
BC23
R23C55
```

解题思路

这道题没什么难的,但是有很多小细节,首先我们要考虑如何判别两种坐标系,然后提取其中的数字,进行进制运算,要注意的是当数据为26的倍数的情况就行了。

代码

#include 
using namespace std;
int pd(char h[10000])
{
    int x;
    if(h[0]!='R')
        return 0;
    if(h[1]>'9'||h[1]<'0')
        return 0;
    for(x=2;h[x]!='C';x++)
    {
        if(h[x]<'0'||h[x]>'9')
            return 0;
    }
    return 1;
}
void r1(char g[10000])
{
    char j[10000];
    long long a=0,b=0;
    long long x=1,k=0,t=0;
    while(g[x]!='C')
    {
        a=a*10+g[x]-'0';
        x++;
    }
    x++;
    while(g[x]!='\0')
    {
        b=b*10+g[x]-'0';
        x++;
    }
    while(b!=0)
    {
        long long d;
        d=b%26;
        if(d==0)
            d=26;
        j[k++]='A'+d-1;
        if(b%26==0)
        {
            b=b/26-1;
        }
        else
            b/=26;
    }
    for(k--;k>=0;k--)
        printf("%c",j[k]);
    printf("%lld",a);
}

void r2(char g[10000])
{
    long long x=0,a=0,b=0,k=1;
    while(g[x]!='\0')
    {
        if(g[x]>='0'&&g[x]<='9')
        {a=a*10+g[x]-'0';}
        x++;
    }
    printf("R%d",a);
    x=0;
    while(g[x]>='A'&&g[x]<='Z')x++;
    x--;
    while(x>=0)
    {
        b=b+(g[x]-'A'+1)*k;
        k*=26;
        x--;
    }
    printf("C%lld",b);
}
int main()
{
    int x,y,n,a,b;
    char g[10000];
    scanf("%d",&n);
    for(y=0;y

今日总结

继续做了一些有关树和查并集的题目,复习了一下前缀和,在后面的几天我准备复习一下二分、搜索、和动态规划。

你可能感兴趣的:(学习,算法)