Codeforces Round #257 (Div. 2)

A.Jzzhu and Children

  计算每个人会出现的轮次数,取最后一个且轮次数最大的,注意是用a[i]-1 % m,倒着扫一遍就行了

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

const int maxn = 100+10;

int n, m;
int a[maxn];

int main()
{
#ifdef LOCAL
    freopen("450A.in", "r", stdin);
#endif
    cin >> n >> m;
    int last_one = n, divide = 0;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    for(int i = n; i >= 1; i--)
        if((a[i]-1) / m > divide) {
            divide = (a[i]-1)/m;
            last_one = i;
        }
    cout << last_one << endl;
    return 0;
}

B.Jzzhu and Sequences

  很容易推出f[i] = f[i-1]+f[i+1],推出每个六个数一个循环,只需要预处理出f[1]~f[6]就行了

  需要注意的是f[i]可能小于-P,需要(f[i]+2*p)%p,以前写过一种保险的取模,小于0的情况,计算其负数是x倍p,加上(x+1)*P再取模

  例如-5, 2  5/2=2  (-5+3*2)%2 = 1

  

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

const long long p = 1000000007;

long long n, sign, ans;
long long f[3];

int main()
{
#ifdef LOCAL
    freopen("450B.in", "r", stdin);
#endif
    cin >> f[0] >> f[1];
    f[2] = f[1] - f[0];
    cin >> n;
    if(((n-1)/3)&1) sign = -1;
    else    sign = 1;
    ans = sign*f[(n-1)%3];
    if(ans > 0) ans %= p;
    else    ans = (ans+2*p)%p;
    cout << ans << endl;
    return 0;
}

C.Jzzhu and Chocolate

  很烦人的题,首先能够得出最后答案是floor(m/x)*floor(n/y),这个卡了我很久...

  一种方法是直接通过数学分析这个式子

  我是自己乱yy:主要考虑是整除情况:如果m%x0==0那么这个解比起其他x是更优的,

  于是我就分情况写得很细,看代码吧。。。就是如果一边能整除,先让其满足

 

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

long long n, m, k, ans;

int main()
{
#ifdef LOCAL
    freopen("450C.in", "r", stdin);
#endif
    cin >> n >> m >> k;
    if(n+m-2 < k)   cout << -1 << endl;
    else {
        if(n % (k+1) == 0)
            ans = n/(k+1)*m;
        else if(m % (k+1) == 0)
            ans = m/(k+1)*n;
        else if(n - 1 >= k && m - 1 >= k)
            ans = max(n/(k+1)*m, m/(k+1)*n);
        else if(n - 1 >= k)
            ans = n/(k+1)*m;
        else if(m - 1 >= k)
            ans = m/(k+1)*n;
        else {
            long long rn = k-(n-1), rm = k-(m-1);
            if(m % (rn+1) == 0)
                ans = m/(rn+1);
            else if(n % (rm+1) == 0)
                ans = n/(rm+1);
            else
                ans = max(m/(rn+1), n/(rm+1));
        }
        cout << ans << endl;
    }
    return 0;
}

D.Jzzhu and Cities

  一开始学长讲的 先求一次最短路(不包括铁路) 然后去扫一遍看 哪些铁路能够删去...因为反例很容易举出就是 当两个相连的城市都需要铁路才能到达centre时,是可能只需要一条铁路的,这种方法会跑两条.错在得出的推论是在考虑1-a的铁路时,是不需要考虑a相邻节点的最短路的,因为他们的最短路更新时是w[a,v]+dis[a]...说不清了!这个推论成立的前提是1-a是通路...

  然后我考虑标记每个点是否使用铁路

  在dijkstra做最短路的时候,我们每次都会选边去更新,我把后面铁路也当作普通边加入,不过做上标记,这样在更新最短路的时候,维护每个点是否经由铁路到达1,注意是要所选的铁路最少:

  如果该点已经使用铁路且使用道路距离<=当前距离  update

  如果该点距离<当前距离  update

  其实就是要多考虑用道路替换铁路情况(尽管dis不变),不过我的代码写得不是很清晰,包含了更多的情况,只是由于每个城市最多取一条铁路,不影响答案

  最后扫一遍记录使用铁路的结点数, ans = k-cnt

  PS:边比较多...听说裸spfa会挂,所以还是dijkstra+heap好写呢

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

const int maxn = 1000000+50;
const long long inf = ~0llu >> 1;

struct Edge{
    int u, v;
    long long  w;
    void init(int u, int v, long long  w) {
        this->u = u;    this->v = v;
        this->w = w;
    }
}edge[maxn*4];

typedef pair<long long, int> pii;

int n, m, k, edgecnt;
int head[maxn], next[maxn];
long long dis[maxn];
bool istrain[maxn], used[maxn];

void addEdge(int u, int v, long long w)
{
    edge[edgecnt].init(u, v, w);
    next[edgecnt] = head[u];
    head[u] = edgecnt++;
}

void dijkstra()
{
    bool done[maxn];
    priority_queue<pii, vector<pii>, greater<pii> > q;
    memset(done, 0, sizeof(done));
    for(int i = 1; i <= n; i++)
        dis[i] = inf;
    dis[1] = 0;
    q.push(make_pair(0, 1));
    while(!q.empty()) {
        pii tmp = q.top();  q.pop();
        int u = tmp.second;
        if(done[u]) continue;
        done[u] = true;
        for(int e = head[u]; e != -1; e = next[e]) {
            int v = edge[e].v;
            if((used[v] && dis[v] == dis[u]+edge[e].w) || dis[v] > dis[u]+edge[e].w) {
                dis[v] = dis[u]+edge[e].w;
                used[v] = istrain[e];
                q.push(make_pair(dis[v], v));
            }
        }
    }
}

int main()
{
#ifdef LOCAL
    freopen("450D.in", "r", stdin);
#endif
    memset(head, -1, sizeof(head));
    memset(next, -1, sizeof(next));
    memset(istrain, 0, sizeof(istrain));
    memset(used, 0, sizeof(used));
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 0; i < m; i++) {
        int u, v;
        long long w;
        scanf("%d%d%lld", &u, &v, &w);
        addEdge(u, v, w);
        addEdge(v, u, w);
    }
//  for(int i = 1; i <= n; i++)
//      cout << dis[i] << endl;
    for(int i = 0; i < k; i++)  {
        int v;
        long long w;
        scanf("%d%lld", &v, &w);
        istrain[edgecnt] = true;
        addEdge(1, v, w);
    }
    dijkstra();
    int cnt = 0;
    for(int i = 2; i <= n; i++)
        cnt += used[i];
    printf("%d\n", k-cnt);
    return 0;
}

  当场只写了ABC,其中A挂了一发,B因为没考虑f[i]+2p的情况,WA,C题虽然搞出来了...不过耗时近1h

  最后rating很不错,300+,rank+260!!!!!!!!就突然从1200+ ->1500

  D题只看了会,有大概思路,但是最短路都不熟0 0  

//写完这个的时候实际上下一场都已经做完了。。。

Codeforces Round #257 (Div. 2),布布扣,bubuko.com

时间: 2024-10-25 21:55:40

Codeforces Round #257 (Div. 2)的相关文章

Codeforces Round #257 (Div. 2) E题:Jzzhu and Apples 模拟

E. Jzzhu and Apples time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Jzzhu has picked n apples from his big apple tree. All the apples are numbered from 1 to n. Now he wants to sell them to

Codeforces Round #257 (Div. 2) A/B/C/D

前三题早就写好了,一直在纠结D A. Jzzhu and Children 题意:就是简单的模拟,给排成一队的孩子分发糖果,每个孩子有至少要得到的糖果数. 然后每次给队头的孩子分发m个糖果,如果他已经得到了足够的糖果(大于等于他想得到的 最少糖果数)那么他就出队,否则他就去队尾.问最后一个孩子的编号. 算法:队列模拟,水题~ #include<cstdio> #include<iostream> #include<cstring> #include<queue&g

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities[最短路] 题目链接:点击打开 题目大意: 在一个国家中有n个城市(城市编号1~n),m条公路和k条铁路,编号为1的城市为首都,为了节约,不需要的铁路需要关闭,问在保证首都到其余所有城市的最短路不变的条件下,最多有多少条铁路是不需要的. 解法: 这个题比较麻烦,保证首都到其余城市的最短路不变,要求出最多有多少条铁路是不需要的,那肯定是从最短路的代码上下手了,我们首先考虑dijkstra算法

Codeforces Round #257(Div.2) D Jzzhu and Cities --SPFA

题意:n个城市,中间有m条道路(双向),再给出k条铁路,铁路直接从点1到点v,现在要拆掉一些铁路,在保证不影响每个点的最短距离(距离1)不变的情况下,问最多能删除多少条铁路 分析:先求一次最短路,铁路的权值大于该点最短距离的显然可以删去,否则将该条边加入图中,再求最短路,记录每个点的前一个点,然后又枚举铁路,已经删去的就不用处理了,如果铁路权值大于该点最短距离又可以删去,权值相等时,该点的前一个点如果不为1,则这个点可以由其他路到达,这条铁路又可以删去. 由于本题中边比较多,最多可以有8x10^

Codeforces Round #257 (Div. 2/A)/Codeforces450A_Jzzhu and Children

解题报告 没什么好说的,大于m的往后面放,,,re了一次,,, #include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; struct node { int x,cd; }num[1000000]; int main() { int n,m,c; cin>>n>>m; int i; for(i=0;i&l

Codeforces Round #257 (Div. 2/B)/Codeforces450B_Jzzhu and Sequences

B解题报告 算是规律题吧,,,x y z -x -y -z 注意的是如果数是小于0,要先对负数求模再加模再求模,不能直接加mod,可能还是负数 给我的戳代码跪了,,, #include <iostream> #include <cstring> #include <cstdio> using namespace std; long long x,y,z; long long n; int main() { cin>>x>>y; cin>&g

Codeforces Round #257 (Div. 1) (Codeforces 449B)

题意:给力一张无向图,有一些边是正常道路,有一些边是铁路,问最多能删除几条铁路使得所有点到首都(编号为1)的最短路长度不变. 思路:求不能删除的铁路数,总数减掉就是答案.先求出首都到所有点的最短路,求完最短路后,枚举除首都外所有点,如果这个点被更新的边中只有铁路,那么就有一条铁路不能删除. 注意:这里求最短路一开始用SPFA在第45个点TLE,最后换成带堆优化Dijkstra #include<cstring> #include<algorithm> #include<cst

Codeforces Round #257 (Div. 1) (Codeforces 449D)

思路:定义f(x)为 Ai & x==x  的个数,g(x)为x表示为二进制时1的个数,最后答案为    .为什么会等于这个呢:运用容斥的思想,如果 我们假设 ai&x==x 有f(x)个,那么 这f(x)个 组成集合的子集 & 出来是 >=x那么我们要扣掉>x的 ...  因为这里我们要求的是 & 之后等于0 一开始1个数为0那么就是 1个数为偶数时加上去,  为奇数时减掉了. 那么就剩下求f(x)    .我们把A[i]和x的二进制 分成  前 (20-k)

Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences (矩阵快速幂)

题目链接:http://codeforces.com/problemset/problem/450/B 题意很好懂,矩阵快速幂模版题. 1 /* 2 | 1, -1 | | fn | 3 | 1, 0 | | fn-1 | 4 */ 5 #include <iostream> 6 #include <cstdio> 7 #include <cstring> 8 using namespace std; 9 typedef __int64 LL; 10 LL mod =