1. 程式人生 > >8.19總結今日

8.19總結今日

其他 namespace gun ios 計算 得到 prime 數值 情況

今天打到一半網站崩了,所以沒能繼續打,話說開火車好煩hhh


開火車D題

題意:

有一個n*m的矩陣,上面一共有k*k個蛋糕,讓你橫向縱向都切k-1刀,問能不能存在一種切法使得切完的所有區域都正好只剩一個蛋糕,如果有,輸出切的位置

解法:

由於橫豎切互不影響,所以我們分開考慮這兩部分,先算出每一行(列)有的蛋糕總數,然後每k個切一次,看看能不能

 1 #include<cstdio>
 2 using namespace std;
 3 const int maxn = 200 + 5;
 4 int g[maxn][maxn];
 5 int row[maxn], col[maxn];
6 int ansr[maxn], ansc[maxn]; 7 8 int main() { 9 int n, m, k; scanf("%d%d%d", &n, &m, &k); 10 for (int i = 0; i < n; i++) 11 for (int j = 0; j < m; j++) 12 scanf("%1d", &g[i][j]); 13 14 //處理每一列 15 for (int j = 0; j < m; j++) 16 for
(int i = 0; i < n; i++) 17 row[j] += g[i][j]; 18 19 int now = 0, cnt = 0, flag = 1; 20 for (int j = 0; j < m; j++) { 21 now += row[j]; 22 if (now < k)continue; 23 else if (now == k) { now = 0, ansr[cnt++] = j; } 24 else if (now > k) { flag = false
; break; } 25 } 26 if (!flag) { printf("NO\n"); return 0; } 27 28 //處理每一行 29 for (int i = 0; i < n; i++) 30 for (int j = 0; j < m; j++) 31 col[i] += g[i][j]; 32 33 now = 0, cnt = 0, flag = 1; 34 for (int i = 0; i < n; i++) { 35 now += col[i]; 36 if (now < k)continue; 37 else if (now == k) { now = 0, ansc[cnt++] = i; } 38 else if (now > k) { flag = false; break; } 39 } 40 if (!flag) { printf("NO\n"); return 0; } 41 42 //如果可以的話 43 printf("YES\n"); 44 printf("%d", ansc[0]+1); 45 for (int i = 1; i < k-1; i++)printf(" %d", ansc[i]+1); 46 printf("\n%d", ansr[0]+1); 47 for (int i = 1; i < k-1; i++)printf(" %d", ansr[i]+1); 48 printf("\n"); 49 50 return 0; 51 }

洛谷P1062

題意:

給出一個多項式的各個項的系數,輸出這個多項式

解法:

超tm細心的模擬,竟然調了這麽長時間,簡直了

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int main() {
 5     int n; cin >> n;
 6     int cnt = n, flag = 0, flag2 = 0;
 7     for (int i = 0; i <= n; i++,cnt--) {
 8         int coe; cin >> coe;
 9         if (coe==0)continue;
10         if (i != n)flag2 = 1;
11         if (flag && coe > 0 && i != 0 && flag2)cout << "+";
12         if (i == 0) {
13             if (coe == -1)cout << "-";
14             else if (coe != 1)cout << coe;
15             cout << "x^" << cnt;
16             flag = 1;
17             continue;
18         }
19         else if (i == n) cout << coe, flag = 1;
20         else if (i == n - 1) {
21             if (coe == -1)cout << "-";
22             else if (coe != 1)cout << coe;
23             cout << "x";
24             flag = 1;
25         }
26         else {
27             if (coe == -1)cout << "-";
28             else if (coe != 1)cout << coe;
29             cout << "x^" << cnt;
30             flag = 1;
31         }
32     }
33     if (!flag)cout << 0;
34     cout << endl;
35     return 0;
36 }

Uva1635

題意:

給定n個數a1,a2····an,依次求出相鄰兩個數值和,將得到一個新數列,重復上述操作,最後結果將變為一個數,問這個數除以m的余數與那些數無關?

例如n=3,m=2時,第一次得到a1+a2,a2+a3,再求和得到a1+2*a2+a3,它除以2的余數和a2無關。1=<n<=10^5, 2=<m<=10^9

解法:

將所有的加法過程列出來可以得到,n個數合並成1個數需要n-1步,且最後的表達式寫成初始項相加的形式 每一項的系數恰好就是一個二項式系數。

問除以m的余數與那些數無關,其實就是問這些因子中哪些是m的倍數。我們還是用分解m質因子的方法,將m的質因子全部先分解出來,然後遍歷每個二項式系數,看他們能否整除這些質因子(如果這個二項式系數改寫成質因子的冪次形式,的這個冪小於m中的這個冪,就不行) 。

除此之外還要學習的就是怎麽計算這個冪次,尤其是被除數為分數的時候,分子的冪次的貢獻為正,分母為負

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 using namespace std;
 5 int vis[100000 + 5];
 6 
 7 int work_quality_factor(int n, int quality_fac[], int frequency[])
 8 {//n是待分解的數,quality_fac[]會存放它包含的質因子,而frequency[]存放對應次數
 9  //如q_f[k]=7,fre[k]=2就表示質因數分解後裏面包含有7,且次數是2
10  //函數返回有幾種質因子,比如分解了25就返回1,分解28返回2
11     int res, temp, i;
12     res = 0;
13     temp = n;
14     for (i = 2; i*i <= temp; i++)
15         if (temp%i == 0)
16         {
17             quality_fac[res] = i;
18             frequency[res] = 0;
19             while (temp%i == 0)
20             {
21                 temp = temp / i;
22                 frequency[res]++;
23             }
24             res++;
25         }
26     if (temp > 1)
27     {
28         quality_fac[res] = temp;
29         frequency[res++] = 1;
30     }
31     return res;
32 }
33 
34 int main() {
35     int n, m;
36     while (scanf("%d%d", &n, &m) != EOF) {
37         n--;
38         memset(vis, 0, sizeof(vis));
39         int fac[100], frq[100];
40         int primenum = work_quality_factor(m, fac, frq);
41 
42         for (int i = 0; i < primenum; i++) {
43             int min_e = frq[i], x, e = 0;
44             // c(n,k)=c(n,k-1)*(n-k+1)/k
45             for (int k = 1; k < n; k++) {
46                 //分成上下兩部分除,上面的冪次的貢獻為正,下面為負
47                 x = n - k + 1;
48                 while (x%fac[i]==0) { x /= fac[i]; e++; }
49                 x = k;
50                 while (x%fac[i]==0) { x /= fac[i]; e--; }
51                 if (e < min_e)vis[k] = 1;
52             }
53         }
54         
55         vector<int>ans;
56         for (int i = 1; i < n; i++)
57             if (!vis[i])ans.push_back(i + 1);
58         printf("%d\n", ans.size());
59         if (!ans.empty()) {
60             printf("%d", ans[0]);
61             for (int i = 1; i < ans.size(); i++)
62                 printf(" %d", ans[i]);
63         }
64         printf("\n");
65     }
66     return 0;
67 }

Uva10820

題意:

給出n,算出小於等於n的所有數中,有幾對互質;

解法:

本質就是求有多少個2元組(x,y)滿足:1 <= x,y <= n,且x與y互素。

除了(1,1)之外,其他所有的x和y都不相同,我們設x<y的二元組有f(n)個,答案就是2f(n)+1 f(n)=phi(2)+phi(3)+...+phi(n);

 1 #include<cstdio>
 2 #include<cmath>
 3 using namespace std;
 4 const int maxn = 5e4 + 5;
 5 int phi[maxn];
 6 
 7 //歐拉函數,求小於n且與n互素的整數個數
 8 int euler_phi(int n) {
 9     int m = (int)sqrt(n + 0.5);
10     int ans = n;
11     for (int i = 2; i <= m; i++) if (n%i == 0) {
12         ans = ans / i*(i - 1);
13         while (n%i == 0)n /= i;
14     }
15     if (n > 1)ans = ans / n*(n - 1);
16     return ans;
17 }
18 
19 //求小於n的所有數的歐拉函數值
20 void phi_table(int n, int *phi) {
21     for (int i = 2; i <= n; i++)phi[i] = 0;
22     phi[1] = 1;
23     for (int i = 2; i <= n; i++)if (!phi[i])
24         for (int j = i; j <= n; j += i) {
25             if (!phi[j])phi[j] = j;
26             phi[j] = phi[j] / i*(i - 1);
27         }
28 }
29 
30 int main() {
31     int n;
32     while (scanf("%d", &n) && n) {
33         phi_table(n, phi);
34         int ans = 0;
35         for (int i = 2; i <= n; i++) ans += phi[i];
36         printf("%d\n", ans + ans + 1);
37     }
38     return 0;
39 }

Uva1636

題意:

扣一下槍沒有響,問再扣一下搶還沒有響的概率,這是把左輪槍

解法:

求出00的概率和01串的概率即可,註意這個是環形的左輪槍

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 char s[1000];
 5 
 6 int main() {
 7     while (scanf("%s", s) != EOF) {
 8         int len = strlen(s);
 9         int pr = 0, pc = 0, gun = 0;
10         s[len] = s[0], s[len + 1] = \0;
11         len = strlen(s);
12         for (int i = 0; i < len - 1; i++) 
13             if (s[i] == 0&&s[i + 1] == 0)pr++;
14         for (int i = 0; i < len-1; i++)
15             if (s[i] == 0)gun++;
16         if (pr*(len-1) > gun*gun)printf("SHOOT\n");
17         else if (pr*(len-1) == gun*gun)printf("EQUAL\n");
18         else printf("ROTATE\n");
19     }
20     return 0;
21 }

Uva580

題意:

一個棧中只能放入U和L,問存在連續3個以上U(危險組合)的個數為幾個

解法:

危險情況數 = 總組合數 - 安全情況數

f[i]表示第i個位置是L的方法總數,那麽f[i]=f[i-1]+f[i-2]+f[i-3]

 1 #include<cstdio>
 2 using namespace std;
 3 typedef long long ll;
 4 ll f[31];
 5 
 6 void generate() {
 7     f[1] = 2, f[2] = 4, f[3] = 7;
 8     for (int i = 4; i <= 30; i++) {
 9         f[i] = f[i - 1] + f[i - 2] + f[i - 3];
10     }
11 }
12 
13 int main() {
14     int n; 
15     generate();
16     while (scanf("%d", &n) && n) {
17         ll ans = (1 << n);
18         printf("%lld\n", ans - f[n]);
19     }
20     return 0;
21 }

8.19總結今日