看了一下C/C++ B組、Java的題,發現掉坑了……
1. 明碼

1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <list> 6 #include <stack> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <queue> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 15 char str[16][16]; 16 17 int main() 18 { 19 long i,j,k,a,b; 20 for (k=1;k<=10;k++) 21 { 22 for (i=0;i<16;i++) 23 { 24 scanf("%ld%ld",&a,&b); 25 // a+=128; b+=128; 26 if (a<0) 27 a+=128; 28 if (b<0) 29 b+=128; 30 for (j=7;j>=0;j--) 31 str[i][7-j]=(a>>j) & 1; 32 for (j=7;j>=0;j--) 33 str[i][15-j]=(b>>j) & 1; 34 } 35 for (i=0;i<16;i++) 36 { 37 for (j=0;j<16;j++) 38 if (str[i][j]==1) 39 printf("*"); 40 else 41 printf(" "); 42 printf("\n"); 43 } 44 printf("\n\n"); 45 } 46 printf("%ld",pow(9,9)); 47 return 0; 48 }
2. 測試次數
我一開始想錯了,這是錯誤代碼
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <list> 6 #include <stack> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <queue> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 15 //[0,1000] 16 //判斷一個數k,<k or >=k 17 //[x,y]判斷(x+y+1)/2,而不是 (x+y)/2 18 //對於x+y+1為奇數的情況,結果>=k的情況最糟,如[1,3] -> [2,3] 19 20 //n=1000為最糟糕的情況 21 22 int main() 23 { 24 long l,r,mid,t=0; 25 l=0; r=1000; 26 while (l<=r) 27 { 28 l=(l+r+1)/2; 29 t++; 30 if (l==1000) 31 break; 32 } 33 printf("%ld",t); 34 return 0; 35 }
沒有注意到:抽樣3部手機參加測試。
http://blog.sina.com.cn/s/blog_3fe961ae0101llmf.html
https://blog.csdn.net/clx55555/article/details/79855677
另,未證明極簡略題解:
C/C++ A組:
航班時間 模擬,創建多幾組測試數據
三體攻擊 不會ac解,騙騙分還是會的,有大神說是線段樹(記錄每一段的最小值)+前綴和(不懂)
比賽的時候搞了一個一維數組,賊復雜,其實這樣就可以了:
1 long n,m,p; 2 scanf("%ld%ld%ld",&n,&m,&p); 3 long a[n][m][p]; 4 a[0][0][0]=1; a[1][0][0]=2; a[2][0][0]=3; 5 printf("%ld %ld %ld",a[0][0][0],a[1][0][0],a[2][0][0]);
全球變暖 bfs,對原來的每一塊賦予一個編號;之后記錄每一個存在的塊
原來的一個島嶼有可能被分成多個島嶼,這多個島嶼只能當一個算,大坑題
倍數問題 我比賽時候的方法是:
對於所有余數為k的數,記錄前三大的數,
對於三個數,若前兩個數的余數確定,則第三個數的余數可求出來
三種情況:三個數的余數相同;兩個數的余數相同;三個數的余數都不同
for i = 0 to mod-1
for j = 0 to mod-1
k = 2*mod - i - j;
if i=j=k ,找到三個最大的余數為i的數(也許不存在)
……
時間復雜度:mod*mod(1 <= mod <= 10^3)
另一種方法:dp[i][j]為j個數之和模mod余數為i的 j個數最大值
時間復雜度:n * mod * 3(j=1,2,3) 1 <= n <= 10^5, 1 <= mod <= 10^3
超時一點點
付賬問題 一個比較好想的貪心,標准差最小,當然是各個數都比較接近,
對n個值排序,從最小的數開始到最大的數,若這個值 小於 剩余需要支付的平均值,則對應的人支付所有的錢,即取該值,
直到這個值 大於等於 剩余需要支付的平均值x,對應的人及以后的人只有支付x即可
C/C++ B組:
遞增三元組 排序+樹狀數組/二分 / 數據范圍太小,直接數組記錄值就可以
螺旋折線 找規律,得到四部分的式子,開long long
日志統計 排序+單調隊列
乘積最大 按照絕對值排序,選最大的前k個數相乘,
若符號為負:
1.若前k個數有負數,從第k+1個開始,找到第一個正數,與前k個數中絕對值最小的負數進行交換;有可能找不到
2.若前k個數有正數,從第k+1個開始,找到第一個負數,與前k個數中絕對值最小的正數進行交換;有可能找不到
求1與2的結果的最大值
若符號為正或零:
就是當前結果
Java A組:
居然找不到題目……
Java B組:
堆的計數
1.完全二叉樹(最底層從左向右放置)
2.父節點的權值一定小於其子節點的權值
3.根節點的值是確定的,值最小
4.任意n個值不相等的數,經過離散化值為1~n,不影響大小關系,
f(n)[以n個點組成的數]的值固定
f(n)=f(m)[左邊的數目]*f(n-m-1)*C(n-1,m) [除根節點之外,選擇任意m個數作為左邊的點]
n!=2 p=log(n)/log(2) 層數
if n-2^p<2^(p-1) m = n-2^p+1 + 2^(p-1)-1 = n-2^(p-1)
else m = 2^(p-1) + 2^(p-1)-1 = 2^p-1

1.記憶化搜索:從n點開始,找m,n-m-1,然后接下來找…… vis記錄之間已經計算過的狀態
(記錄一下需要算多少值)
2.c(x,y)中x,y的值的變化:
(4,2)、(5,3)、(6,3)、(7,3)、(8,4)、(9,5)、(10,6)、(11,7)、(12,7)、(13,7)、(14,7)、(15,7)……
兩種情況:x++,y++ x++[n-2^p<2^(p-1)]
Way2:
37 #include <cstdio> 38 #include <cstdlib> 39 #include <cstring> 40 #include <cmath> 41 #include <list> 42 #include <stack> 43 #include <vector> 44 #include <set> 45 #include <map> 46 #include <queue> 47 #include <algorithm> 48 #include <iostream> 49 using namespace std; 50 #define mod 1000000009 51 long long f[100005]; 52 53 long long chu(long long s) 54 { 55 if (s==0) 56 return 1; 57 long ci=mod-1-1; 58 long long r=1; 59 while (ci) 60 { 61 if ((ci & 1)==1) 62 r=r*s%mod; 63 s=s*s%mod; 64 ci=ci>>1; 65 } 66 return r; 67 } 68 69 int main() 70 { 71 long n,m,p,i; 72 long long value=1; 73 scanf("%ld",&n); 74 f[0]=1; f[1]=1; 75 //f(n)=f(m)*f(n-m-1)*C(n-1,m) 76 m=0; 77 for (i=2;i<=n;i++) 78 { 79 p=(long)(log(i)/log(2)); 80 if (i - (1<<p) < (1<<(p-1)) ) 81 { 82 m++; 83 //C(i-1,m) <- C(i-2,m-1) 84 value=value * (i-1) %mod * chu(m) %mod; 85 f[i]=f[m] * f[i-m-1] %mod *value %mod; 86 } 87 else 88 { 89 //C(i-1,m) <- C(i-2,m) 90 value=value * (i-1) %mod * chu(i-m-1) %mod; 91 f[i]=f[m] * f[i-m-1] %mod * value %mod; 92 } 93 } 94 printf("%ld",f[n]); 95 return 0; 96 } 97 // 1 1 2 3 8 20 80
Way1:
1 /* 2 1.ÍêÈ«¶þ²æÊ÷(×îµ×²ã´Ó×óÏòÓÒ·ÅÖÃ) 3 4 2.¸¸½ÚµãµÄȨֵһ¶¨Ð¡ÓÚÆä×Ó½ÚµãµÄȨֵ 5 6 3.¸ù½ÚµãµÄÖµÊÇÈ·¶¨µÄ£¬Öµ×îС 7 8 4.ÈÎÒân¸öÖµ²»ÏàµÈµÄÊý£¬¾¹ýÀëÉ¢»¯ÖµÎª1~n£¬²»Ó°Ïì´óС¹ØÏµ£¬ 9 f(n)[ÒÔn¸öµã×é³ÉµÄÊý]µÄÖµ¹Ì¶¨ 10 11 f(n)=f(m)[×ó±ßµÄÊýÄ¿]*f(n-m-1)*C(n-1,m) [³ý¸ù½ÚµãÖ®Í⣬ѡÔñÈÎÒâm¸öÊý×÷Ϊ×ó±ßµÄµã] 12 13 n!=2 p=log(n)/log(2) ²ãÊý 14 if n-2^p<2^(p-1) m = n-2^p+1 + 2^(p-1)-1 = n-2^(p-1) 15 else m = 2^(p-1) + 2^(p-1)-1 = 2^p-1 16 17 1 18 2 3 19 4 5 6 7 20 8 21 22 1 23 2 3 24 4 5 6 7 25 8 9 10 11 12 26 27 28 1.¼ÇÒ仯ËÑË÷£º´Ónµã¿ªÊ¼£¬ÕÒm,n-m-1£¬È»ºó½ÓÏÂÀ´ÕÒ¡¡ vis¼Ç¼֮¼äÒѾ¼ÆËã¹ýµÄ״̬ 29 (¼Ç¼һÏÂÐèÒªËã¶àÉÙÖµ) 30 31 2.c(x,y)ÖÐx,yµÄÖµµÄ±ä»¯: 32 (4,2)¡¢(5,3)¡¢(6,3)¡¢(7,3)¡¢(8,4)¡¢(9,5)¡¢(10,6)¡¢(11,7)¡¢(12,7)¡¢(13,7)¡¢(14,7)¡¢(15,7)¡¡ 33 Á½ÖÖÇé¿ö:x++,y++ x++[n-2^p<2^(p-1)] 34 35 */ 36 37 #include <cstdio> 38 #include <cstdlib> 39 #include <cstring> 40 #include <cmath> 41 #include <list> 42 #include <stack> 43 #include <vector> 44 #include <set> 45 #include <map> 46 #include <queue> 47 #include <algorithm> 48 #include <iostream> 49 using namespace std; 50 #define mod 1000000009 51 long long f[100005]; 52 53 long long chu(long long s) 54 { 55 if (s==0) 56 return 1; 57 long ci=mod-1-1; 58 long long r=1; 59 while (ci) 60 { 61 if ((ci & 1)==1) 62 r=r*s%mod; 63 s=s*s%mod; 64 ci=ci>>1; 65 } 66 return r; 67 } 68 69 long dfs(long d) 70 { 71 long m,p,i; 72 p=(long)(log(d)/log(2)); //d!=1,0 73 if (d - (1<<p) < (1<<(p-1)) ) 74 m = d - (1<<(p-1)); 75 else 76 m = (1<<p) - 1; 77 if (f[m]==-1) 78 dfs(m); 79 if (f[d-m-1]==-1) 80 dfs(d-m-1); 81 f[d]=f[m] * f[d-m-1] %mod; 82 for (i=d-1;i>d-1-m;i--) 83 f[d]=f[d]*i %mod; 84 for (i=2;i<=m;i++) 85 f[d]=f[d]*chu(i) %mod; 86 } 87 88 int main() 89 { 90 long n,i; 91 scanf("%ld",&n); 92 f[0]=1; f[1]=1; 93 for (i=2;i<=n;i++) 94 f[i]=-1; 95 //f(n)=f(m)*f(n-m-1)*C(n-1,m) 96 dfs(n); 97 printf("%ld",f[n]); 98 return 0; 99 } 100 // 1 1 2 3 8 20 80
