[校内模拟题1]

竞赛时间:????年??月??日??:??-??:??
题目名称 算 游 运

名称 sum tour lucky

输入 sum.in tour.in lucky.in

输出 sum.out tour.out lucky.out

每个测试点时限 1 秒 1 秒 1 秒

内存限制 512MB 512MB 512MB

测试点数目 10 10 10

每个测试点分值 10 10 10

是否有部分分 无 无 是

题目类型 传统 传统 传统
注意事项(请务必仔细阅读):
 
 

【问题背景】

zhx 帮他妹子做数学题。

【问题描述】

求:

$\sum\limits_{x=1}^{N}\sum\limits_{y=1}^{M} x^y$
 如 N=3, M=3,这个值为 1^1+1^2+1^3+2^1+2^2+2^3+3^1+3^2+3^3=56。

【输入格式】

仅一行,包含两个数 N 和 M.  

【输出格式】

仅一行,包含所求的答案 mod 10^9 + 7 的值。 

【样例输入】

3 3

【样例输出】

56

【数据范围与规定】

对于50%的数据,所有1 ≤ 𝑁,𝑀 ≤ 1000。 对于100%的数据,所有1 ≤ 𝑁,𝑀 ≤ 50000。

——————————————————————————————————————————————

50%,直接暴力模拟。

100%,可知每个数的1~M次幂是一个等比数列。

用等比数列求和公式,注意mod1000000007公式除法要用逆元。

code

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 typedef long long LL;
 7 int N, M, MOD = 1e9+7;
 8 LL ans;
 9 
10 LL fPow(LL a, LL b) {
11     LL ans = 1;
12     while (b) {
13         if (b & 1) ans = ans * a % MOD;
14         b >>= 1;
15         a = a * a % MOD;
16     } return ans;
17 } 
18 
19 int main() {
20     freopen("sum.in", "r", stdin); 
21     freopen("sum.out", "w", stdout); 
22     cin >> N >> M;
23     for (int i = 1; i <= N; ++ i) {
24         if (i == 1) ans = (ans + M) % MOD;
25         ans = (ans + 1ll * (i * (fPow(i, M) - 1) % MOD) * fPow(i - 1, MOD - 2)) % MOD;
26     }
27     cout << ans << endl;
28     return 0;
29 }

 

 

 

【问题背景】

zhx 和他的妹子出去玩。

【问题描述】

zhx 和他的妹子去一个国家旅游,共有 N 个旅游景点,N-1 条双向连接的道 路将它们联通起来,每一条道路有固定长度。一开始 zhx 位于 1 号景点。 现在希望你能够求出旅行长度最小的方案,使得每个景点至少被访问到一次。 

【输入格式】

第一行两个整数 N,代表景点数目。 接下来 N-1 行,每行三个整数 s, t, w,表示有一条从 s 到 t 的双向道路,长 度为 w。s 和 t 的编号从 1 开始。

【输出格式】

一行一个整数,代表能够访问每个景点至少一次的方案的最小旅行长度。

【样例输入】

3 1 2 3 2 3 3

【样例输出】

6

【样例输入】

3 1 2 3 1 3 3

【样例输出】

9

【数据规模与约定】

对于30%的数据,1 ≤ 𝑁 ≤ 10。

对于70%的数据,1 ≤ 𝑁 ≤ 1000。 对于100%的数据,1 ≤ 𝑁 ≤ 50000,1 ≤ 𝑤 ≤ 1000。

对于100%的数据,1 ≤ 𝑁 ≤ 50000,1 ≤ 𝑤 ≤ 1000。

——————————————————————————————————————————————

节点数为N,边数为N-1,显然是一颗树。

尝试几种走法即可得知,无论怎样走,大部分边都要走两次。只走一次的边组成了一条连续的以根为起点某一叶子节点为终点的路径。

求最小长度,只走一次的边应尽量大。因此问题转换为求单源最长路。SPFA或直接广搜皆可。

注意1 ≤ 𝑁 ≤ 50000,1 ≤ 𝑤 ≤ 1000。会爆int(大概)注意longlong的使用。

考试code

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

typedef long long LL;
const LL INF = 9223372036854775806ll;
const int MAXN = 100010;
int N; 
LL sumw, dis[MAXN], maxdis;
int head[MAXN*2], ecnt;
bool vis[MAXN]; 

struct Edge{
    int next, node, value;
}e[MAXN*2];

inline int read() {
    int num = 0, f = 1; char ch = getchar();
    while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
    while (isdigit(ch)) { num = num * 10 + ch - '0'; ch = getchar(); }
    return num * f;
}

inline void Add_Edge(int s, int t, int w) {
    e[++ecnt].next = head[s]; 
    e[ecnt].node = t;
    e[ecnt].value = w;
    head[s] = ecnt;
}

void slove(int s) {
    memset(vis, false, sizeof(vis));
    queue<int> q;
    dis[s] = 0;
    vis[s] = true;
    q.push(s);
    while (!q.empty()) {
        int h = q.front();
        q.pop();
        int i, v;
        for (i = head[h]; i ; i = e[i].next) {
            v = e[i].node;
            if (dis[v] > dis[h] + e[i].value) {
                dis[v] = dis[h] + e[i].value;
                if (!vis[v]) {
                    q.push(v);
                    vis[v] = true;
                }
            }
        }
    }
}

int main() {
    freopen("tour.in", "r", stdin);
    freopen("tour.out", "w", stdout); 
    N = read();
    int i, s, t, w;
    for (i = 1; i <= N - 1; ++ i) {
        s = read(); t = read(); w = read();
        Add_Edge(s, t, w);
        Add_Edge(t, s, w);
        sumw += w;
        dis[i] = INF;
    }    
    slove(1);
    for (int i = 1; i <= N; ++ i) maxdis = max(maxdis, dis[i]);
    cout << (LL)sumw * 2 - maxdis << endl;
    return 0;
}

测试挂了四个点QWQ

第二个第三个A了。最后四个大数据A了。但中间莫名溢出?!

QWQ

结果经历一番艰苦卓绝的Debug,发现是边读入边初始化错了

    for (i = 1; i <= N - 1; ++ i) {
        s = read(); t = read(); w = read();
        Add_Edge(s, t, w);
        Add_Edge(t, s, w);
        sumw += w;
        dis[i] = INF;
    }    

dis[i]只更新到了N-1,因此WA掉了第一个点,之后的数据也因此出现玄学错误。

改为

    for (i = 2; i <= N; ++ i) {
        s = read(); t = read(); w = read();
        Add_Edge(s, t, w);
        Add_Edge(t, s, w);
        sumw += w;
        dis[i] = INF;
    }    

SPFA里好像还忘写了一个vis[h]=false;

QWQ四十分真心疼

 

【问题背景】

zhx 和妹子们玩数数游戏。

【问题描述】

仅包含 4 或 7 的数被称为幸运数。 一个序列的子序列被定义为从序列中删去若干个数,剩下的数组成的新序列。 两个子序列被定义为不同的当且仅当其中的元素在原始序列中的下标的集合不 相等。对于一个长度为N的序列,共有2^N个不同的子序列。(包含一个空序列)。 一个子序列被称为不幸运的,当且仅当其中不包含两个相同的幸运数。 对于一个给定序列,求其中长度恰好为 K 的不幸运子序列的个数,答案 mod 10^9+7 输出。

【输入格式】

第一行两个正整数 N,K,表示原始序列的长度和题目中的 K。 接下来一行 N 个整数 ai,表示序列中第 i 个元素的值。

【输出格式】

仅一个数,表示不幸运子序列的个数。(mod 10^9+7)

【样例输入】

3 2 1 1 1

【样例输出】

3

【样例输入】

4 2 4 7 4 7

【样例输出】

4

【样例解释】

对于样例 1,每个长度为 2 的子序列都是符合条件的。 对于样例2, 4个不幸运子序列元素下标分别为:{1, 2}, {3, 4}, {1, 4}, {2, 3}。 注意下标集{1, 3}对应的子序列不是“不幸运”的,因为它包含两个相同的幸运数 4.

【数据规模与约定】

对于50%的数据,1 ≤ 𝑁 ≤ 16。 对于70%的数据,1 ≤ 𝑁 ≤ 1000, 𝑎𝑖 ≤ 10000。 对于100%的数据,1 ≤ 𝑁 ≤ 100000,𝐾 ≤ 𝑁,1 ≤ 𝑎𝑖 ≤ 109。

——————————————————————————————————————————————

都错题了QWQ原来不是4或7而是含4或7的数字啊。。。

但是竟然还有三十分。。。

贴一个大佬链接

%%%

 

posted @ 2018-07-25 18:37  wakelin  阅读(195)  评论(0编辑  收藏  举报