2019CCPC网络选拔赛签到题题解
前言
因為實力不濟,沒能通過網絡賽拿到晉級的名額,心情沉重,故作此文記錄本次網絡賽的點滴收獲。其中包含1001 ^ & ^、1006 Shuffle Card、1007 Windows Of CCPC、1008 Fishing Master的題解。
題解
1001 ^ & ^
題目傳送門
題目分析:
要找到使(AxorC)(A \ xor \ C)(A?xor?C)&(BxorC)(B \ xor \ C)(B?xor?C) 的值最小,就是要使兩邊進行&運算時,對應二進制位數字都不同。然后我們可以這樣做:
我們模擬上述過程最終發現規律C = A & B。
易錯提示:
- A和B的范圍都是有可能比int類型大的,所以應該用long long。
- 題面更改過一次,沒有及時刷新又會踩坑。
- 注意位運算符的優先級是非常低,比那些條件判斷的運算符還低,建議使用位運算符時多用括號。
代碼如下
#include <bits/stdc++.h>using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int maxn = 1e5 + 10; int T; ll a, b, ans, value;int main() {ios::sync_with_stdio(false);cin.tie(0); // freopen("t.txt", "r", stdin);cin >> T;while (T--) {cin >> a >> b;ans = a & b;value = (a ^ ans) & (b ^ ans);if ((ans == 0) && (value == 0))cout << "1" << endl;elsecout << ans << endl;}return 0; }1006 Shuffle Card
題目傳送門
題目分析:
可以說這是一道簡單的模擬題:
- 當aia_iai?被操作時,就將aia_iai?放入一個棧中(也可以開數組來存,最后逆序訪問)
- 完成m次操作后,取出棧中所有的元素,如果取出來的數沒有被訪問過,就把它輸出并標記。
- 最后遍歷a數組,把上一步沒有訪問過的元素都輸出。
易錯提示:
神奇的人什么坑都能踩,如果循環中會改變棧中元素的數量,就不要將循環條件寫成下面這樣[捂臉]
代碼如下
#include <bits/stdc++.h>using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int maxn = 1e5 + 10; int T, n, m, t; int a[maxn], vis[maxn]; stack<int> s;int main() {ios::sync_with_stdio(false);cin.tie(0); // freopen("t.txt", "r", stdin);cin >> n >> m;for (int i = 0; i < n; i++)cin >> a[i];for (int i = 0; i < m; i++) {cin >> t;s.push(t);}while (!s.empty()) {t = s.top();s.pop();if (!vis[t]) {cout << t << " ";vis[t] = 1;}}for (int i = 0; i < n; i++) {if (!vis[a[i]])cout << a[i] << " ";}return 0; }1007 Windows Of CCPC
題目傳送門
題目分析
通過觀察很容易發現規律,將2k?2k2^{k}*2^{k}2k?2k平均分成4塊,每塊的大小是2k?1?2k?12^{k-1}*2^{k-1}2k?1?2k?1。而第2,4塊與第1塊相同,第3塊和第1塊相反(若第1塊某位置為’C’,則第3塊對應位置為’P’;反之同理)。于是,我們就可以利用遞推關系進行打表,再根據每一次詢問輸出就可以了。
代碼如下
#include <bits/stdc++.h>using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int maxn = 1024 + 10; int T, k, str[maxn][maxn]; int t, tt;void init() {memset(str, 0, sizeof(str));str[1][1] = 1;for (int i = 1; i <= 10; i++) {t = 1 << (i - 1);tt = 1 << i;for (int j = 1; j <=t; j++) {for (int k = t + 1; k <=tt; k++)str[j][k] = str[j][k - t];}for (int j = t + 1; j <= tt; j++) {for (int k = t + 1; k <= tt; k++)str[j][k] = str[j - t][k];for (int k = 1; k <= t; k++)str[j][k] = (!str[j][k + t]);}} }int main() {ios::sync_with_stdio(false);cin.tie(0);// freopen("t.txt", "r", stdin);cin >> T;init();while (T--) {cin >> k;for (int i = 1; i <= (1 << k); i++) {for (int j = 1; j <= (1 << k); j++)if (str[i][j]) putchar('C');else putchar('P');putchar('\n');}}return 0; }1008 Fishing Master
題目傳送門
題目分析:
大家都很明確這道題是用貪心法來做,做錯的一般都是沒有找到正確的貪心策略(包括我)。如果你一直在感覺正確和提交上去就WA之間徘徊,就可以會發現這道題的核心就是:判斷抓到一條魚之后,是等待上一條魚煮網,還是去抓下一條魚。
想破頭后得到:
- 如果煮魚時間tit_iti?小于k,可以對小于k的tit_iti?進行降序排序,優先煮花費時間比較長的魚。這樣就可以使最后等待煮魚的時間盡可能少。
- 如果煮魚時間tit_iti?大于k,那就需要用(ti/k)?k(t_i/k)*k(ti?/k)?k(除的結果需要向下取余)的時間去抓魚,盡可能不去等待,剩下的ti?(ti/k)?kt_i-(t_i/k)*kti??(ti?/k)?k就當成小于k的來處理就可以了。
代碼如下
#include <bits/stdc++.h>using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int maxn = 1e5 + 10; int T, n, k, t[maxn]; ll ans, cnt, temp;int main() {ios::sync_with_stdio(false);cin.tie(0);// freopen("t.txt", "r", stdin);cin >> T;while (T--) {cin >> n >> k;cnt = 0, ans = k; //cnt表示可以不用等待直接去抓魚的次數,ans表示總耗時for (int i = 0; i < n ; i++){cin >> temp;t[i] = temp % k; //只保留小于t[i]-(t[i]/k)*k部分,小于kcnt += temp / k; }sort(t, t + n, greater<int>()); //降序排序(從大到小)if (cnt >= n) { //如果可以不用等待直接去抓魚的次數大于捕魚數ans += cnt * k; //多出來部分可以直接算抓完所有魚后,等待煮魚的部分(原本就是煮魚的時間)for (int i = 0; i < n; i++)ans += t[i];} else {ans += (ll)(n - 1) * k; //因為總共的抓魚時間就是n*kfor (int i = n - cnt - 1; i < n; i++)ans += t[i];}cout << ans <<endl;}return 0; }總結
真的很不甘心,幾乎是流著淚寫完這篇博客的。作為1008的主碼成員,我為自己沒有遲遲沒有找到適當的策略感到痛心。在比賽中也暴露了團隊的一些問題:
- 算法水平不足,像題解中寫道的主席數,后綴自動機,杜教篩……等算法都還沒有過接觸,還是要注意提高算法學習的廣度。
- 團隊配合嚴重不足,因為沒有聚在一起打,隊友協作少,沒能體現團隊的優勢。
- 進行沒有必要的死磕,如果做不出來應該讓給隊友做,或者跟隊友講思路讓隊友幫忙debug,隊友遇到困難可以幫忙出數據找問題。
繩鋸木斷,水滴石穿。
如履薄冰,如臨深淵。
總結
以上是生活随笔為你收集整理的2019CCPC网络选拔赛签到题题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java实现ftp的上传、下载和删除
- 下一篇: Tomcat的安装与配置(新手向)