• FJUT2019暑假周赛一题解


    A.排队问题*-*

    题意就是有长度为L的序列,每位的取值可以是'f'或者'm',问不包含'fff'和'fmf'的个数。

    打表找规律

    不难找出递推公式为F[n] = F[n-1] + F[n-3] + F[n-4]。

    然后直接遍历就可以了...突然发现L范围很小,我写了个矩阵快速幂...

    多组数据且模数不固定,矩阵快速幂即可

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 
      5 int n,mod;
      6 
      7 struct M {
      8     ll p[4][4];
      9     M(int num) {
     10         memset(p,0,sizeof p);
     11         for (int i = 0; i < 4; i++) {
     12             p[i][i] = num;
     13         }
     14     }
     15 
     16     M operator * (M b) {
     17         M c(0);
     18         for (int i = 0; i < 4; i++) {
     19             for (int j = 0; j < 4; j++) {
     20                 c.p[i][j] = 0;
     21                 for (int k = 0; k < 4; k++) {
     22                     c.p[i][j] = (c.p[i][j] + (p[i][k]*b.p[k][j])%mod)%mod;
     23 
     24                 }
     25             }
     26         }
     27         return c;
     28     }
     29 
     30     M operator ^ (ll k) {
     31         M c(1),a = *this;
     32         while (k) {
     33             if (k&1) {
     34                 c = a*c;
     35             }
     36             a = a*a;
     37             k >>= 1;
     38         }
     39         return c;
     40     }
     41 
     42 };
     43 M a(0),b(0);
     44 int solve() {
     45     M c(0);
     46 
     47     if (n == 0) {
     48         return 0;
     49     } else if (n <= 4) {
     50         return a.p[4-n][0]%mod;
     51     }
     52     c = b^(n-4);
     53     c = c*a;
     54     return c.p[0][0]%mod;
     55 }
     56 
     57 string s;
     58 
     59 void db() {
     60     for (int i = 1; i <= 15; i++) {
     61         int p = pow(2.0,i),tot = 0,cnt = 0;
     62         for (int j = 0; j < p; j++) {
     63             int tmp = 1;
     64             s = "";
     65             for (int k = 1; k <= i; k++) {
     66                 if (tmp&j) {
     67                     s += 'f';
     68                 } else {
     69                     s += 'm';
     70                 }
     71                 tmp <<= 1;
     72             }
     73             for (int k = 0; k < int(s.size())-2; k++) {
     74                 if (s[k] =='f' && s[k+1] == 'm' && s[k+2] == 'f') {
     75                     cnt++;
     76                     break;
     77                 } else if (s[k] =='f' && s[k+1] == 'f' && s[k+2] == 'f') {
     78                     cnt++;
     79                     break;
     80                 }
     81             }
     82             tot++;
     83         }
     84         cout << i << ' ' << p-cnt << endl;
     85     }
     86 }
     87 /*
     88     f_i = f_{i-1} + f_{i-3} +f_{i-4};
     89     1 0 1 1
     90     1 0 0 0
     91     0 1 0 0
     92     0 0 1 0
     93 */
     94 int main() {
     95     ios_base::sync_with_stdio(0);
     96     cin.tie(0);
     97     db();
     98 
     99     a.p[0][0] = 9;
    100     a.p[1][0] = 6;
    101     a.p[2][0] = 4;
    102     a.p[3][0] = 2;
    103     b.p[0][0] = 1;
    104     b.p[0][2] = 1;
    105     b.p[0][3] = 1;
    106     b.p[1][0] = 1;
    107     b.p[2][1] = 1;
    108     b.p[3][2] = 1;
    109     while (cin >> n >> mod) {
    110         cout << solve() << endl;
    111     }
    112     return 0;
    113 }
    View Code

    此处应有严格证明递推公式的由来,然而我不会。。。

    B.就差把标程贴上去了

    公式都已经放出来了

    一个数的长度也就是len(x) = log(x)/log(10) + 1,这里我们取对数就可以得到len(n!) = 1/2*log10(2.0*PI*n) + n*log10(n/e)+1。

    这里其实就够了,当然你可以继续化简到和我代码一样= =

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define pi (acos(-1))
     5 ll n,d;
     6 
     7 void solve() {
     8     cin >> n;
     9     d = (int) ((0.5*log(2*pi*n) + n*log(n)-n) / log (10));
    10     cout << d+1 << endl;
    11 }
    12 
    13 int main() {
    14     ios_base::sync_with_stdio(0);
    15     cin.tie(0);
    16     int _;
    17     cin >> _;
    18     while (_--) {
    19         solve();
    20     }
    21     return 0;
    22 }
    View Code

    C.假算法天下第一

    搞了半天 搞懂了题意,就是一个数组分k次(至多),然后要求每部分尽量小,再求这k个部分的最大值。

    emmm就是一个最大值最小化问题,LRJ的《算法入门经典》里面有详细介绍。

    我们可以用二分思考这道题,我们使用二分确定一个值x,使得x尽量小并且每个区间都不大于它。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 #define pi (acos(-1))
      5 int n,k;
      6 ll p[100005];
      7 bool flag[100005];
      8 
      9 void work(ll l, ll r) {
     10     while(l < r) {
     11         bool flag1 = false;
     12         ll mid = (l + r) / 2;
     13         ll sum = 0, kide = 1;
     14 
     15         for(int i = 0; i < n; i++) {
     16             if(sum < mid && sum + p[i] < mid) {
     17                 sum += p[i];
     18             }
     19             else {
     20                 if(p[i] < mid) {
     21                     kide++;
     22                     sum = 0;
     23                     sum += p[i];
     24                 } else {
     25                     flag1 = true;
     26                     break;
     27                 }
     28             }
     29         }
     30 
     31         if(flag1 || kide > k) {
     32             l = mid + 1;
     33         } else {
     34             r = mid;
     35         }
     36     }
     37 
     38     ll sum = 0;
     39 
     40     for(int i = n - 1; i >= 0; i--) {
     41         if(sum < l && sum + p[i] < l) {
     42             sum += p[i];
     43         }
     44         else {
     45             sum = 0;
     46             flag[i] = true;
     47             sum += p[i];
     48         }
     49     }
     50 
     51     int di = 1;
     52     int pos = 0;
     53 
     54     for(int i = n - 1; i >= 0; i--) {
     55         if(flag[i]) {
     56             di++;
     57         }
     58     }
     59 
     60     if(di != k) {
     61         for(int i = 0; i < n && di != k; i++) {
     62             if(!flag[i]) {
     63                 flag[i] = true;
     64                 di++;
     65             }
     66         }
     67     }
     68 
     69     ll tmp = 0, ans = 0;
     70 
     71     for(int i = 0; i < n; i++) {
     72         if(flag[i] && i != n - 1) {
     73             tmp += p[i];
     74             ans = max(tmp, ans);
     75             tmp = 0;
     76         } else if(i != n - 1) {
     77             tmp += p[i];
     78         } else {
     79             tmp += p[i];
     80         }
     81         //cout << tmp << endl;
     82     }
     83 
     84     ans = max(tmp, ans);
     85     cout << ans << endl;
     86 }
     87 
     88 void solve() {
     89     cin >> n >> k;
     90     n--;
     91     ll sum = 0;
     92 
     93     for(int i = 0; i < n; i++) {
     94         cin >> p[i];
     95         sum += p[i];
     96     }
     97     if (k == 1) {
     98         cout << sum << endl;
     99     } else {
    100         work(0, sum);
    101     }
    102 }
    103 
    104 int main() {
    105     ios_base::sync_with_stdio(0);
    106     cin.tie(0);
    107     solve();
    108     return 0;
    109 }
    View Code

     然后我发现了个神奇的代码

    ZB果然nb = =

    D.美好的一天从WA+1开始

    题意就不说了,反悔贪心的题目,首先我们按照日期进行贪心,然后用堆维护一下选区的物品,当遇到某件物品不能选取但是他的值却大于以前选过的某个,就进行替换。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define pi (acos(-1))
     5 int n;
     6 int na,nb;
     7 vector<pair<int,int>> p(100005);
     8 ll sum,avg;
     9 
    10 void init() {
    11 }
    12 
    13 void solve() {
    14     while (cin >> n) {
    15         sum = 0;
    16         priority_queue<int,vector<int>,greater<int>> q;
    17         for (int i = 1; i <= n; i++) {
    18             cin >> p[i].second >> p[i].first;
    19         }
    20         sort(p.begin()+1,p.begin()+1+n);
    21         for (int i = 1; i <= n; i++) {
    22             if (q.size() < p[i].first) {
    23                 q.push(p[i].second);
    24                 sum += p[i].second;
    25             } else {
    26                 if (p[i].second > q.top()) {
    27                     sum -= q.top();
    28                     sum += p[i].second;
    29                     q.pop();
    30                     q.push(p[i].second);
    31                 }
    32             }
    33         }
    34         cout << sum << endl;
    35     }
    36 }
    37 
    38 int main() {
    39     ios_base::sync_with_stdio(0);
    40     cin.tie(0);
    41     solve();
    42     return 0;
    43 }
    View Code

    E.矮死 发 矮死 破色波

    没什么好说的,优先喝b就行了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define pi (acos(-1))
     5 int n,a,b;
     6 int na,nb;
     7 int p[200005];
     8 
     9 void solve() {
    10     cin >> n >> a >> b;
    11     na = a;
    12     nb = b;
    13     for (int i = 1; i <= n; i++) {
    14         cin >> p[i];
    15     }
    16     for (int i = 1; i <= n; i++) {
    17         if (p[i]) {
    18             if (na > 0 && nb < b) {
    19                 na--;
    20                 nb++;
    21             } else if (nb > 0) {
    22                 nb--;
    23             } else if (na > 0) {
    24                 na--;
    25             } else {
    26                 cout << i-1 << endl;
    27                 return;
    28             }
    29         } else {
    30             if (nb > 0) {
    31                 nb--;
    32             } else if (na > 0) {
    33                 na--;
    34             } else {
    35                 cout << i-1 << endl;
    36                 return;
    37             }
    38         }
    39     }
    40     cout << n << endl;
    41 }
    42 
    43 int main() {
    44     ios_base::sync_with_stdio(0);
    45     cin.tie(0);
    46     solve();
    47     return 0;
    48 }
    View Code

    排版乱糟糟的,好久没写博客了= =,数学公式将就着看看吧= =,我也不知道博客园怎么弄Latex。

  • 相关阅读:
    数据库中的左连接(left join)和右连接(right join)区别
    ajax提交form表单资料详细汇总
    javaScript 删除确认实现方法总结分享
    web.xml文件配置详解以及实例说明
    java时间处理工具类--DateUtils
    Oracle安装后忘记用户名或密码+创建新登陆用户
    zabbix server 端安装
    zabbix 介绍
    nginx + uWSGI 为 django 提供高并发
    nginx-1.10.3 编译安装
  • 原文地址:https://www.cnblogs.com/xenny/p/11300317.html
Copyright © 2020-2023  润新知