命題者:frostray
這題的目標是讀取 N 個字串,並將它們以 "字串1"+"字串2"+"字串3"
的格式輸出。
程式碼說明
if (i > 0) res += "+";
+
i > 0
(即非第一個字串),則這個字串的前面加上 +
。res += '\"' + s + '\"';
s
是當前讀入的字串,而 '\"'
代表雙引號(因為 "
在 C++ 內部需要用 \
轉義)。s = "hamster"
,這行程式會讓 res += "\"hamster\""
,即字串 hamster
會被雙引號包圍。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
string res = "";
for (int i = 0; i < n; i++) {
string s;
cin >> s;
if (i > 0) res += '+';
res += '\"' + s + '\"';
}
cout << res << '\n';
return 0;
}
命題者:BIR
先閱讀題序,然後小心實作即可。
掃過棋盤上三行,紀錄在那裏面的己方棋子數量還有總分,紀錄駒台上的總分,最後在紀錄整個棋盤上的己方棋子總分,然後檢查王將位置,小心判斷各種條件。
#include<iostream>
int main() {
char board[9][9];
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
cin>>board[i][j];
}
}
int mygo[7];
int urgo[7];
for(int i=0;i<7;i++)
{
cin>>mygo[i];
}
for(int i=0;i<7;i++)
{
cin>>urgo[i];
}
int flag1=0;
int flag2=0;
int flag3=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<9;j++)
{
if(board[i][j]=='K')
{
flag1=1;
break;
}
}
}
int num=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<9;j++)
{
if(board[i][j]=='R' ||board[i][j]=='B'||board[i][j]=='G'||board[i][j]=='S'||board[i][j]=='N'||board[i][j]=='L'||board[i][j]=='P')
{
num++;
}
}
}
if(num>=10)
{
flag2=1;
}
int score=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<9;j++)
{
if(board[i][j]=='R')
{
score+=5;
}
if(board[i][j]=='B')
{
score+=5;
}
if(board[i][j]=='G')
{
score+=1;
}
if(board[i][j]=='S')
{
score+=1;
}
if(board[i][j]=='N')
{
score+=1;
}
if(board[i][j]=='L')
{
score+=1;
}
if(board[i][j]=='P')
{
score+=1;
}
}
}
score+=mygo[0]*5;
score+=mygo[1]*5;
score+=mygo[2]*1;
score+=mygo[3]*1;
score+=mygo[4]*1;
score+=mygo[5]*1;
score+=mygo[6]*1;
if(score>=24)
{
flag3=1;
}
if(flag1==1 && flag2==1 && flag3==1)
{
for(int i=3;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(board[i][j]=='R')
{
score+=5;
}
if(board[i][j]=='B')
{
score+=5;
}
if(board[i][j]=='G')
{
score+=1;
}
if(board[i][j]=='S')
{
score+=1;
}
if(board[i][j]=='N')
{
score+=1;
}
if(board[i][j]=='L')
{
score+=1;
}
if(board[i][j]=='P')
{
score+=1;
}
}
}
if(score>=31)
{
cout<<"WIN";
}
else
{
cout<<"DRAW";
}
}
else
{
cout<<"LOSS";
}
return 0;
}
命題者:a!!!
用陣列紀錄目前所有桶子的剩餘容量,每個詢問用迴圈從起點一直往右檢查當前水桶有沒有容量可以裝並更新水桶容量,直到水都被裝進水桶裡或是最後一個水桶被檢查完了就結束迴圈
#include<iostream>
using namespace std;
int c[200005], w[200005];
int main(){
int n;
cin >> n;
for(int i = 1; i <= n; i++) cin >> c[i];
int q;
cin >> q;
long long sum = 0;
while(q--){
int cur, x;
cin >> cur >> x;
for(int i = cur; i <= n; i++){
if(w[i] + x > c[i]){
x -= c[i] - w[i];
w[i] = c[i];
}
else{
w[i] += x;
x = 0;
break;
}
}
sum += x;
}
for(int i = 1; i <= n; i++) cout << w[i] << ' ';
cout << '\n' << sum << '\n';
}
命題者:BIR
這題有兩種解法,一種是處理浮點數時使用double來保證足夠的精度,另一種是直接把浮點數當作字串處理,如果'.'之前是'1'的話就一定是1.0000,否則把'0.'去掉,題目中保證會把不足的位數補零,剩下的部分用int讀入很方便,然後就可以正常用整數比大小了。
#include<iostream>
int main() {
int n;
cin>>n;
double price;
double rate;
double ans;
double flag=0;
double min=1000000;
for(int i=1;i<=n;i++)
{
cin>>price>>rate;
if(min>price*rate)
{
ans=i;
min=price*rate;
flag=0;
}
else if(min == price*rate)
{
flag=1;
}
}
if(flag==1)
{
cout<<"iwantshampoo";
}
else
{
cout<<ans;
}
return 0;
}
命題者:高睿(sakinu)
先用二維陣列與雙重迴圈將每個人做過哪些題目讀進來,再換個順序得出每道題被哪些人做過,並另外紀錄這道題是否有被做過,沒被做過的題目輸出
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 1e3+5;
string names[MAX_N];
int arr[MAX_N][MAX_N];
int main() {
ios::sync_with_stdio(0), cin.tie(0);
int n,m;
cin >> n >> m;
for(int i=0;i<n;i++ ) {
cin >> names[i];
for(int j=0;j<m;j++) {
cin >> arr[i][j];
}
}
for(int i=0;i<m;i++) {
int cnt = 0;
for(int j=0;j<n;j++) {
if(arr[j][i] == 1) {
if(cnt != 0) cout << " ";
cout << names[j];
cnt++;
}
}
if(cnt == 0) {
cout << "-1";
}
cout << "\n";
}
}
命題者:高睿(sakinu)
先分成三種 case:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAX_N = 1e5+5, mod = 1e9+7;
int l[MAX_N];
int r[MAX_N];
int cnt[MAX_N];
int n;
int MUL(int x, int y) {
return x*y%mod;
}
void add(int &x, int y) {
x += y;
if(x >= mod) x-=mod;
if(x < 0) x+=mod;
}
int getlrNum(int pos) { //得到 pos 這個位置共有幾種英文字母可選
int ll = l[pos];
int rr = r[pos];
if('Z' < ll && rr < 'a') return 0;
if('Z' < ll && ll < 'a') ll = 'a';
if('Z' < rr && rr < 'a') rr = 'Z';
if('a' <= ll) return rr-ll+1;
if(rr <= 'Z') return rr-ll+1;
return (rr-ll+1)-('a'-'Z'-1);
}
void solve() {
string scist = "scist";
string SCIST = "SCIST";
cin >> n;
if(n<5) {
cout << 0 << "\n";
return;
}
for(int i=0;i<n;i++) cin >> l[i];
for(int i=0;i<n;i++) cin >> r[i];
int ans = 0;
for(int pre_len=0;pre_len<=5;pre_len++) { //前綴的長度
int nxt_len = 5-pre_len; //後綴的長度
vector<int> pos; //五個字元的位置
for(int j=0;j<pre_len;j++) pos.push_back(j);
for(int j=0;j<nxt_len;j++) pos.push_back(n-(nxt_len)+j);
int num = 1;
for(int j=0;j<5;j++) { //五個字元的選法乘積
int cnt = 0;
if(l[pos[j]] <= scist[j] && scist[j] <= r[pos[j]]) cnt++;
if(l[pos[j]] <= SCIST[j] && SCIST[j] <= r[pos[j]]) cnt++;
num = MUL(num, cnt);
}
int ll = pre_len;
int rr = n-(nxt_len)-1;
for(int j=ll;j<=rr;j++) { //其他所有字元的選法乘積
num = MUL(num, getlrNum(j));
}
add(ans, num);
if(n == 5) break;
}
cout << ans << "\n";
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0);
solve();
}
命題者:BIR
這題要注意各種細節卑鄙的小手段,首先雖然輸送帶轉一格看似需要移動所有輸送帶上的食材一格,但其實也可以想成是操作的人往反方向移動一格,只需要改動表示目前所在位置的一個整數就好了。接著如果使用和初始食材一樣大小的陣列,每次有食材被拿走就把那格改成-1之類的是不行的,因為如果在一連串空格左右被要求不斷來回走動的話,計算一下複雜度會發現超過1e9太多了,會得到TLE,這裡需要善用linked list來記錄目前的食物位置,直接移動指定方向上的下一個食物,接著看到題目直接叫hanoi,可能可以想到要使用stack來實作這些包著漢堡的皮的河內塔們,如果開了跟漢堡數量*食材數量的二維陣列,就會超過容量上限得到MLE,解決以上的所有考點並且小心實作語法即可AC,記得開個IO優化。
上面是出題者原話,這邊幫忙簡化一下:
#include<bits/stdc++.h>
int main() {
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n; cin >> n;
int pos=1;
int linked_list[n+1];
int left_linked[n+1];
int right_linked[n+1];
for(int i=1;i<=n;i++)
{
cin>>linked_list[i];
left_linked[i]=i-1;
right_linked[i]=i+1;
}
left_linked[1]=n;
right_linked[n]=1;
int m;cin>>m;
vector<stack<int>> ham(m+1);
int q;cin>>q;
string opr;
for(int i=0;i<q;i++)
{
cin>>opr;
if(opr=="clockwise")
{
pos=left_linked[pos];
}
else if(opr=="counterclockwise")
{
pos=right_linked[pos];
}
else if(opr=="take")
{
int num;cin>>num;
if(ham[num].empty()||linked_list[pos]<=ham[num].top())
{
ham[num].push(linked_list[pos]);
right_linked[left_linked[pos]]=right_linked[pos];
left_linked[right_linked[pos]]=left_linked[pos];
}
else
{
cout<<"Oops!";return 0;
}
}
else if(opr=="move")
{
int start;cin>>start;
int end;cin>>end;
if(ham[start].empty())
{
cout<<"test";return 0;
}
else if(ham[end].empty())
{
ham[end].push(ham[start].top());
ham[start].pop();
}
else if(ham[start].top()<=ham[end].top())
{
ham[end].push(ham[start].top());
ham[start].pop();
}
else
{
cout<<"Oops!";return 0;
}
}
}
for(int i=1;i<=m;i++)
{
if(ham[i].empty())
{
cout<<"-1";
}
else
{
while(!ham[i].empty())
{
cout<<ham[i].top()<<" ";
ham[i].pop();
}
}
cout<<"\n";
}
return 0;
}
命題者:4yu
tag: 模擬、建表
這題也是純粹照著題目的規則來模擬即可,首先要依照格式讀入 N * M 的二維陣列,可以在過程中順便維護最大最小值以及它們的座標,具體做法跟當初培訓報名表單中的進階班小測驗找極值差不多,只是從一維變成二維而已,然後就是要開始從最高點走到最低點,需要枚舉八個方位,可以利用 2024/11/10 線上週所教的實作技巧:建表,將每個方位的 x、y 變化量先存在陣列裡,再用迴圈去跑,在判斷方位的部分,線上週沒來上課的可能會這樣寫:
輸出測資就能拿 10 分了
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<vector<int>> grid;
int m, n;
cin >> m >> n;
grid.resize(m, vector<int>(n));
for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) cin >> grid[i][j];
if(m == 4) cout << "YES\nDL+D+DL\n";
else if(m == 5) cout << "NO\n";
else if(m == 10) cout << "YES\nL+DL+L+DL+DR+D+D+D+DR+UR+R+DR+R+R+UR+U+UL+DL+UL+UL+L\n";
}
N = M = 3,自行寫判斷式枚舉即可
#include <bits/stdc++.h>
using namespace std;
// 建表 8 個移動方向
// 0 1 2 3 4 5 6 7
// 順時鐘:上 右上 右 右下 下 左下 左 左上
const int dx[8] = {-1,-1,0,1,1,1,0,-1};
const int dy[8] = {0,1,1,1,0,-1,-1,-1};
const string ds[8] = {"U","UR","R","DR","D","DL","L","UL"};
vector<vector<int>> grid;
int m, n;
string path;
// 判斷是否在圖尺寸範圍中
bool in_range(int x, int y) { return (0 <= x && x < m && 0 <= y && y < n); }
// 從最高點走到最低點
bool GD(pair<int, int> max_pos, pair<int, int> min_pos)
{
int x = max_pos.first, y = max_pos.second;
while (make_pair(x, y) != min_pos)
{
int best_d = -1;
int min_height = grid[x][y];
// 遍歷 8 個方向,找到最低的鄰居
for (int i=0; i<8; ++i)
{
int nx = x + dx[i];
int ny = y + dy[i];
if (in_range(nx,ny) && grid[nx][ny] < min_height)
{
min_height = grid[nx][ny];
best_d = i;
}
}
// 如果八方都不能走就無法走到最低點
if (best_d == -1) return false;
path += ds[best_d] + "+";
x += dx[best_d];
y += dy[best_d];
}
return true;
}
int main()
{
cin >> m >> n;
grid.resize(m, vector<int>(n));
int max_h = -1, min_h = 10001;
pair<int, int> max_pos, min_pos;
// 讀入二維圖並記錄最大最小值
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
cin >> grid[i][j];
if (grid[i][j] > max_h)
{
max_h = grid[i][j];
max_pos = {i, j};
}
if (grid[i][j] < min_h)
{
min_h = grid[i][j];
min_pos = {i, j};
}
}
}
bool ans = GD(max_pos, min_pos);
if(ans)
{
path.pop_back();
cout << "YES\n" << path << "\n";
}
else cout << "NO\n";
}
命題者:hamster
觀察到7這個數字已經被刪掉
所以可以將原本數字的10進制變成9進制
然後注意轉成進制後每一位的 7 8 要改成 8 9 (對應7被刪除的情況)就可以了
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void solve() {
ll n;
cin >> n;
vector<ll> res;
while (n) {
res.push_back((n % 9 >= 7) ? (n % 9 + 1) : (n % 9));
n /= 9;
}
for (int i = res.size() - 1; i >= 0; i--) {
cout << res[i];
}
cout << '\n';
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
}
命題者:高睿(sakinu)
子題一 (
子題二 (
字串處理:
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 1e5+5;
int arr[MAX_N][26];
int need[26];
void add(int pos) {
string s;
cin >> s;
s = s + ',';
int lit=0;
for(int rit=0;rit<s.size();rit++) {
if(s[rit] == ',') { //lit~rit 是一種組合
char type = s[lit++];
arr[pos][type-'A'] += stoi(s.substr(lit, rit-lit));
lit = rit+1;
}
}
for(int j=0;j<26;j++)
arr[pos][j] += arr[pos-1][j];
}
bool ok(int pos) {
for(int i=0;i<26;i++)
if(arr[pos][i] < need[i])
return 0;
return 1;
}
void query(int n) {
for(int i=0;i<26;i++)
need[i] = 0;
string s;
cin >> s;
s = s + ',';
int lit=0;
for(int rit=0;rit<(int)s.size();rit++) {
if(s[rit] == ',') { //lit~rr 是一種組合
char type = s[lit++];
need[type-'A'] = stoi(s.substr(lit, rit-lit));
lit = rit+1;
}
}
int ll = 1, rr = n+1;
while(ll!=rr) {
int mid = (ll+rr)/2;
if(ok(mid))
rr = mid;
else
ll = mid + 1;
}
cout << (ll==n+1?-1:ll) << "\n";
}
void solve() {
int n,q;
cin >> n >> q;
for(int i=1;i<=n;i++) {
add(i);
}
while(q--) {
query(n);
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
solve();
}
命題者:高睿(sakinu)
解法:同基礎班 pE
#include<基礎班 pE>