Week 2

1.P1007 独木桥

Week 2_第1张图片

1. 本题核心:将两位士兵相遇后掉头---->两人交换身份到达原本对方的终点

2.min:所有人都朝离自己距离最近的端点走,反正所有人的速度都一样,也不存在相遇;然后在循环中两两比较谁花的时间最长。

3.max:所有人都朝离自己距离最远的端点走,遇到对方直接越过继续走,求其中的最长时间。

#include 
using namespace std;

int l,n,a[5010];

int main()
{
    int sum1=0,sum2=0;
    cin>>l>>n;
    for(int i=0;i>a[i];
        sum1 = max(min(l+1-a[i],a[i]),sum1);//所有士兵到自己离最近的端点中的最长距离
        sum2 = max(max(l+1-a[i],a[i]),sum2);//所有士兵到离自己最远的端点中的最长距离
    }
    cout<

2.P1223 排队接水

Week 2_第2张图片

1.这题要求找到最短的等待时间,很明显的贪心加sort排序
2.因为本题要求输出明年时间最短的排队顺序,所以我设置了两个数组(动态数组a也可以直接写成普通数组,本来打算找到一个min,弹出一个min,所以用的vector,结果忘记了每弹出一个元素,角标i也会-1,那vector就没用了),a[ ]用来保存原来的输入顺序,t[ ]排序后用来与a[ ]进行比较,依次找到最短的接水时间。
3.最短的平均等待时间,我这里用的是,从最长的那段时间开始,依次n个人的等待时间的总和。

#include 
using namespace std;

int t[1010];
vector a;

int main()
{
    int n;
    double ave,sum=0;
    cin>>n;
    for(int i=0;i>t[i];
        a.push_back(t[i]);
    }

    sort(t,t+n);

    int temp = -1; // 将temp移到循环外面以避免重复初始化
    for(int i=0;i

3.P1803 凌乱的yyy / 线段覆盖

Week 2_第3张图片

 一开始我用的是两个独立的数组,但是单用两个数组a[]和b[],两者之间没有逻辑关系,单对b[]排序时,a[]的顺序不会改变,所以要将a[]和b[]打包成一个结构体,并整体排序(排序具体规则见注释)。

然后就是简单判断了:如果下一场比赛的开始时间>上一场比赛的结束时间,那么yyy就能参加了,即sum++。

!!!结构体排序一定要自己定义cmp。

本题数组开得格外大(本蒟蒻卑微求解)

//结构体排序
#include 
using namespace std;

struct Time{
    int a;
    int b;
}oj[3000000];//数组开大点,虽然本蒟蒻也不知道为什么

//排序规则:先从小到大排结束时间,结束时间相等时,从小到大排开始时间
bool cmp(Time x,Time y)
{
    if(x.b==y.b) return x.a>n;
    for(int i=0;i>oj[i].a>>oj[i].b;
    }

    sort(oj,oj+n,cmp);

    int temp=-1;//放在循环里会重复赋初值为-1
    for(int i=0;i=temp){
            sum++;
            temp = oj[i].b;
        }
    }
    cout<

4.P1031 [NOIP2002 提高组] 均分纸牌

 Week 2_第4张图片

虽然但是,我确实没有看到这个题哪里要用贪心(doge)。
最开始是想着算出平均数之后,先找到最大的那个数,再向左向右移,尽可能使得它和与它相邻的堆的纸牌数变成平均值,但是思考了半天,好像也没有很好的解决办法(大抵是水平太低,转化不成代码,卑微)。
所以……参考了一下题解,发现本题只需要求解最少移动次数,不用管到底是怎么移动的,反正只要纸牌数不等于就要移动
所以依次从左往右,不断将每一堆的纸牌数都变成平均数,如果a[i]==ave直接跳过,每移动一次,次数+1。

写了两种(其实原理一样),以下是先将每堆纸牌数都-ave,然后a[i]!=0时(即原来的纸牌数不等于ave)都要移动。

#include 
using namespace std;

int a[110];

int main()
{
    int n,sum=0,ans=0;
    cin>>n;
    for(int i=0;i>a[i];
        sum += a[i];
    }
    int ave = sum/n;
    
    for(int i=0;i

第二种就是将a[i]直接与ave进行比较,不相等就移动。

#include 
using namespace std;

int a[110];

int main()
{
    int n,sum=0,ans=0;
    cin>>n;
    for(int i=0;i>a[i];
        sum += a[i];
    }
    int ave = sum/n;

    for(int i=0;i

你可能感兴趣的:(算法,c++)