2017年江西理工大学C语言程序设计竞赛(高级组)

问题 A: 求近似值
 1 #include <stdio.h>
 2 #include <time.h>
 3 #include <stdlib.h>
 4 using namespace std;
 5 
 6 #define ll long long
 7 const ll M = 9e18;
 8 const ll MOD = 9932017;
 9 struct Node {
10     ll m[2][2];
11 };
12 
13 ll a[4966010];
14 
15 Node mul(Node a, Node b) {
16     Node A;
17     for(int i = 0; i < 2; ++i) {
18         for(int j = 0; j < 2; ++j) {
19             A.m[i][j] = 0;
20             for(int k = 0; k < 2; ++k) {
21                 A.m[i][j] = (A.m[i][j] + a.m[i][k] * b.m[k][j] % MOD) % MOD;
22             }
23         }
24     }
25     return A;
26 }
27 
28 ll q(Node a, ll num) {
29     Node AA;
30     AA.m[0][0] = AA.m[1][1] = 1;
31     AA.m[0][1] = AA.m[1][0] = 0;
32     while(num) {
33         if(num & 1) AA = mul(AA, a);
34         a = mul(a, a);
35         num >>= 1;
36     }
37     return 2LL * AA.m[0][0] - 1;
38 }
39 int main() {
40     ll n;
41     int t;
42     scanf("%d", &t);
43     while(t--) {
44         scanf("%lld", &n);
45         n %= 4966009;
46         if(n > 2483005) n = 2483005*2-n-1;
47         if(a[n]){
48             printf("%lld\n", a[n]);
49             continue;
50         }
51         Node A;
52         A.m[0][0] = A.m[1][1] = 11;
53         A.m[1][0] = 60;
54         A.m[0][1] = 2;
55         //printf("%lld\n", q(A, n));
56         a[n] = q(A, n);
57         printf("%lld\n", a[n]);
58     }
59     return 0;
60 }
超级模法师
  • n % i = n - n / i * i (n / i 表示下取整)
  • 所以所求 = n * m - sum(n/i * i) (i从1到m)
  • 由于,n的第j个因子和第j+1个因子间(左开右闭),的任意数k,有n / k = n / n的第j+1个因子
  • 所以我们用sqrt(n)的时间求出所有n的因子即可,然后相邻的两个用下等差数列求和公式很容易就能算出
  • 求得过程有些坑点需要注意,首先是注意m的大小,m的大小可能位于n的两个因子之间
  • 然后是,求和公式那里也需要先求下余,再算乘法,这样就需要注意因为有个除2,所以要判断用哪一项能整除2,除完后再求余
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cmath>
 4 #define ll long long
 5 using namespace std;
 6 const int N = 1e7;
 7 const ll mod = 1e9+7;
 8 ll n , ans = 0 , m , a , b;
 9 
10 int main(){
11     ll tmp =  500000004;
12     scanf("%lld%lld",&n,&m);
13     if(m > n){
14         ans = ((m - n) % mod) * (n % mod) % mod;
15         m = n;
16     }
17     if(m <= N){
18         for(int i = 1 ; i <= m ; i ++){
19             ans += (n % i);
20         }
21 
22     }else{
23         for(int i = 1 ; ; i ++){
24             ll x = n / i , y = n / (i + 1) + 1;
25             if(y > m){
26                 continue;
27             }else if(x >= m && y <= m){
28                 ans += (((n % m) + (n % y)) % mod) * ((((m - y + 1) % mod) * tmp) % mod) % mod;
29 
30             }else{
31                 ans += (((n % x) + (n % y)) % mod) * ((((x - y + 1) % mod) * tmp) % mod) % mod;
32             }
33             if(y <= N){
34                 for(int k = 1 ; k < y ; k ++){
35                     ans += (n % k);
36                 }
37                 break;
38             }
39         }
40     }
41     printf("%lld\n",ans % mod);
42 }
Combinationaritilize
#include "stdio.h"
#include "stdlib.h"
int main(void)
{
    int num;
    scanf("%d",&num);
    if(num&(num-1))
        printf("no");
    else
        printf("yes");
    return 0;
}
字符串最大表示
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cstring>
 4 using namespace std;
 5 int Next[1000005];
 6 char s[1000005];
 7 int main(){
 8     int T;
 9     scanf("%d",&T);
10     while(T --){
11         scanf("%s",s);
12         int tlen = strlen(s);
13         int j, k;
14         j = 0; k = -1; Next[0] = -1;
15         while(j < tlen){
16             if(k == -1 || s[j] == s[k])
17                 Next[++j] = ++k;
18             else
19                 k = Next[k];
20         }
21         
22         printf("%d\n",tlen / (tlen - Next[tlen]));
23     }
24 }
DATE ALIVE

二分图匹配,然后上模版

 1 #include <iostream>
 2 #include <time.h>
 3 #include <stdio.h>
 4 #include <vector>
 5 #include <string.h>
 6 using namespace std;
 7 const int maxn = 509*2;
 8 int n, x, y, sum;
 9 bool vis[maxn];
10 int use[maxn];
11 vector<int> v[maxn];
12 bool Find(int x){
13     for(int i = 0; i < v[x].size(); ++i){
14         int xx = v[x][i];
15         if(!vis[xx]){
16             vis[xx] = true;
17             if(!use[xx] || Find(use[xx])){
18                 use[xx] = x;
19                 return true;
20             }
21         }
22     }
23     return false;
24 }
25 int main(){
26     int n, m, k;
27     scanf("%d%d%d", &n, &m, &k);
28     for(int i = 0; i < k; ++i){
29         scanf("%d%d", &x, &y);
30         v[x].push_back(y+501);
31     }
32     memset(use, 0, sizeof(use));
33     for(int i = 1; i <= n; ++i){
34         memset(vis, false, sizeof(vis));
35         if(Find(i)) sum ++;
36     }
37     printf("%d\n", sum);
38     for(int i = 1; i <= x; ++i){
39         v[i].clear();
40     }
41     //printf("%.3lf\n", (double)clock()/CLOCKS_PER_SEC);
42     return 0;
43 }
敏感的小明
 1 #include<bits/stdc++.h>
 2 #include<stdio.h>
 3 using namespace std;
 4 int flag[15];
 5 int main(){
 6     memset(flag,0,sizeof(flag));
 7     int n;
 8     cin>>n;
 9     int num;
10     cin>>num;
11     for(int i=0;i<num;i++){
12         int x;
13         cin>>x;
14         flag[x]=1;
15     }
16     for(int i=n;;i++){
17         int j=i;
18         int fg=1;
19         if(flag[j%10]==1){
20             fg=0;
21         }else{
22             do{
23             int y=j%10;
24             if(flag[y]==1){
25                 fg=0;
26                 break;
27             }
28             j=j/10;
29             }while(j!=0);
30         }
31         if(fg==1){
32             cout<<i<<endl;
33             break;
34         }
35     }
36     return 0;
37 }
初中数学
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<bits/stdc++.h>
 4 using namespace std;
 5 int a[1050][1050];
 6 int main(){
 7     int n,m;
 8     cin>>n>>m;
 9     int cnt=0;
10     for(int i=1;i<n+1;i++){
11         for(int j=1;j<m+1;j++){
12             cin>>a[i][j];
13             if(a[i][j]!=0){
14                 cnt+=2;
15             }
16         }
17     }
18     for(int i=1;i<n+1;i++){
19         for(int j=1;j<m+1;j++){
20             if(a[i][j]-a[i-1][j]>0){
21                 cnt+=a[i][j]-a[i-1][j];
22             }
23             if(a[i][j]-a[i+1][j]>0){
24                 cnt+=a[i][j]-a[i+1][j];
25             }
26             if(a[i][j]>a[i][j-1])
27                 cnt+=a[i][j]-a[i][j-1];
28             if(a[i][j]>a[i][j+1])
29                 cnt+=a[i][j]-a[i][j+1];
30         }
31     }
32     cout<<cnt<<endl;
33 
34 }

 

posted @ 2017-12-03 17:39  樱花落舞  阅读(704)  评论(0编辑  收藏  举报