【SoundHound Inc. Programming Contest 2018】 解题报告

【SoundHound Inc. Programming Contest 2018】 解题报告

比赛地址

Tasks
– F
– Acrostic
– Ordinary Beauty
– Saving Snuuk
– Plus Graph

AB不讲。

C – Ordinary Beauty

Statement

Let us define the beauty of a sequence $ (a_1,… ,a_n)$ as the number of pairs of two adjacent elements in it whose absolute differences are $d$.
For example, when $d=1$, the beauty of the sequence $(3, 2, 3, 10, 9)$ is $3$.

There are a total of $n^m$sequences of length $m$ where each element is an integer between $1$ and $n$ (inclusive).
Find the beauty of each of these $n^m$ sequences, and print the average of those values.

Idea

计算两个相邻数 beauty 的平均值,然后乘上 m-1 就可以了,因为答案和顺序无关。

Code

#include 
#define ll long long
using namespace std;
ll n, m, d;
int main(){
    scanf("%lld%lld%lld", &n, &m, &d);
    double temp;
    if(d==0) temp=n;
    else temp=(n-d)*2;//temp是一个间隔的所有情况之和,平均值要除以 n^2
    printf("%.10lf
", (double)(m-1)/n*temp/n);//防止卡精度
}

D – Saving Snuuk

Statement

Kenkoooo is planning a trip in Republic of Snuke.
In this country, there are $n$ cities and $m$ trains running.
The cities are numbered $1$ through $n$, and the $i$-th train connects City $u_i$ and $v_i$ bidirectionally.
Any city can be reached from any city by changing trains.

Two currencies are used in the country: yen and snuuk.
Any train fare can be paid by both yen and snuuk.
The fare of the $i$-th train is $a_i$ yen if paid in yen, and $b_i$ snuuk if paid in snuuk.

In a city with a money exchange office, you can change $1$ yen into $1$ snuuk.
However, when you do a money exchange, you have to change all your yen into snuuk.
That is, if Kenkoooo does a money exchange when he has $X$ yen, he will then have $X$ snuuk.
Currently, there is a money exchange office in every city, but the office in City $i$ will shut down in $i$ years and can never be used in and after that year.

Kenkoooo is planning to depart City $s$ with $10^{15}$ yen in his pocket and head for City $t$, and change his yen into snuuk in some city while traveling.
It is acceptable to do the exchange in City $s$ or City $t$.

Kenkoooo would like to have as much snuuk as possible when he reaches City $t$ by making the optimal choices for the route to travel and the city to do the exchange.
For each $i=0,…,n-1$, find the maximum amount of snuuk that Kenkoooo has when he reaches City $t$ if he goes on a trip from City $s$ to City $t$ after $i$ years.
You can assume that the trip finishes within the year.

Idea

因为只要兑换一次货币,按 yen 和 snuuk 跑两遍最短路,距离加起来最后取最小值即可。

Code

#include 
#define maxn 200010
#define INF 0x3f3f3f3f 
using namespace std;
struct Edge{
    int to,next,val;
    Edge(int a=0,int b=0,int c=0){
        to=a,next=b,val=c;
    }
}l[maxn<<1][2];
int head[maxn][2],cnt[2],n,m;
long long dis[maxn][2],res[maxn];
void SPFA(int s,int k){
    queueq;int vis[maxn];
    memset(vis,0,sizeof(vis));
    memset(dis,INF,sizeof(dis));
    q.push(s),dis[s][k]=0;
    while(!q.empty()){
        int hq=q.front();q.pop();vis[hq]=0;
        for (int i=head[hq][k];i;i=l[i][k].next){
            int v=l[i][k].to;
            if (dis[v][k]>dis[hq][k]+l[i][k].val){
                dis[v][k]=dis[hq][k]+l[i][k].val;
                if (!vis[v]) vis[v]=1,q.push(v);
            }
        }
    }
    for (int i=1;i<=n;i++) res[i]+=dis[i][k];
}
void add(int a,int b,int c,int k){
    l[++cnt[k]][k]=Edge(b,head[a][k],c);
    head[a][k]=cnt[k];
}
int main(){
    ios::sync_with_stdio(false);
    int s,t; cin>>n>>m>>s>>t;
    for (int i=1;i<=m;i++){
        int x,y,a,b;
        cin>>x>>y>>a>>b;
        add(x,y,a,0),add(y,x,b,1);
        add(y,x,a,0),add(x,y,b,1);
    }
    SPFA(s,0),SPFA(t,1);
    for (int i=n-1;i>=1;i--) res[i]=min(res[i+1],res[i]);
    for (int i=1;i<=n;i++) cout<<1000000000000000-res[i]<

E - Plus Graph

Statement

Kenkoooo found a simple connected graph.
The vertices are numbered $1$ through $n$.
The $i$-th edge connects Vertex $u_i$ and $v_i$, and has a fixed integer $s_i$.

Kenkoooo is trying to write a positive integer in each vertex so that the following condition is satisfied:

  • For every edge $i$, the sum of the positive integers written in Vertex $u_i$ and $v_i$ is equal to $s_i$.

Find the number of such ways to write positive integers in the vertices.

Idea