給三個正整數,求眾數以及去重之後從大排到小的順序
不使用 for 迴圈的方式:
int x[3];
void sol() {
cin >> x[0] >> x[1] >> x[2];
if (x[1] < x[2])
swap(x[1], x[2]);
if (x[0] < x[1])
swap(x[0], x[1]);
if (x[1] < x[2])
swap(x[1], x[2]);
if (x[0] == x[2])
cout << 3 << " ";
else if (x[0] == x[1])
cout << 2 << " ";
else if (x[1] == x[2])
cout << 2 << " ";
else
cout << 1 << " ";
cout << x[0] << " ";
if (x[1] != x[0])
cout << x[1] << " ";
if (x[2] != x[1])
cout << x[2] << " ";
cout << endl;
}
給一個加密過程以及加密過的字串,求加密前的字串
加密過程:
使用一個 deque 紀錄目前的字串,以支援題目所需的操作
#define MAXN 105
#define MAXM 1000005
int n, m;
bool odd[MAXN];
string x, s[MAXN];
void sol() {
cin >> n >> m;
for (int i = n - 1; i >= 0; i--) {
cin >> s[i];
int cnt = 0;
for (char c: s[i])
cnt += (c - '0');
odd[i] = cnt % 2;
}
cin >> x;
deque<char> dq;
for (char c: x)
dq.push_back(c);
for (int i = 0; i < n; i++) {
deque<char> tmp;
for (int j = m - 1; j >= 0; j--) {
if (s[i][j] - '0') {
tmp.push_back(dq.back());
dq.pop_back();
}
else {
tmp.push_front(dq.back());
dq.pop_back();
}
}
if (odd[i])
for (int j = 0; j < m / 2; j++)
swap(tmp[j], tmp[j + (m + 1) / 2]);
dq = tmp;
}
for (int i = 0; i < m; i++)
cout << dq[i];
cout << endl;
}
有多個以 /
或是 \
呈現
本題的重點在要如何以非線性的時間求出每個鏡子上下左右的鏡子是哪個
可以觀察到:
觀察到以上兩種性質的話我們就可以想到兩種方法:
時間複雜度:
以下提供第二種作法
#define MAXN 250005
#define MAXM 30005
int n, m;
const int trans[2][4] = {
{1, 0, 3, 2},
{3, 2, 1, 0}
};
struct Mirror {
int F, S, t;
bool operator <(Mirror _a) {
if (F != _a.F)
return F < _a.F;
else
return S < _a.S;
}
} x[MAXN], y[MAXN];
Mirror now = {0, 0, 0};
int ans = 0, dir = 0;
void update(Mirror a) {
now = a;
dir = trans[a.t][dir];
return;
}
void sol() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> x[i].F >> x[i].S >> x[i].t;
y[i] = {x[i].S, x[i].F, x[i].t};
}
sort(x, x + n);
sort(y, y + n);
while (1) {
if (dir == 0) {
Mirror tmp = {now.S, now.F + 1, 0};
auto qq = lower_bound(y, y + n, tmp);
if (qq == y + n || (*qq).F != now.S)
break;
Mirror res = {(*qq).S, (*qq).F, (*qq).t};
update(res);
}
else if (dir == 1) {
Mirror tmp = {now.F, now.S + 1, 0};
auto qq = lower_bound(x, x + n, tmp);
if (qq == x + n || (*qq).F != now.F)
break;
Mirror res = *qq;
update(res);
}
else if (dir == 2) {
Mirror tmp = {now.S, now.F, 0};
auto qq = lower_bound(y, y + n, tmp);
if (qq == y || (*qq).F != now.S)
break;
qq--;
Mirror res = {(*qq).S, (*qq).F, (*qq).t};
update(res);
}
else if (dir == 3) {
Mirror tmp = {now.F, now.S, 0};
auto qq = lower_bound(x, x + n, tmp);
if (qq == x || (*qq).F != now.F)
break;
qq--;
Mirror res = *qq;
update(res);
}
ans++;
}
cout << ans << endl;
}
給兩個長度分別為
內積的算法為:
可以觀察到,對於任意一個子區間
綜合以上幾點我們可以發現,對於每個區間
若定義一個函數
至於
時間複雜度:
#define MAXN 1005
#define MAXM 1000005
int n, m;
int x[MAXN], y[MAXN];
int cal(int i, int j) {
int sum = 0;
int ans = -INF;
int mn = 0;
for (; i < n && j < m; i++, j++) {
sum += x[i] * y[j];
ans = max(ans, sum - mn);
mn = min(mn, sum);
}
return ans;
}
void sol() {
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> x[i];
for (int j = 0;j < m; j++)
cin >> y[j];
int ans = -INF;
for (int i = 0; i < n; i++)
ans = max(ans, cal(i, 0));
for (int j = 0; j < m; j++)
ans = max(ans, cal(0, j));
reverse(x, x + n);
for (int i = 0; i < n; i++)
ans = max(ans, cal(i, 0));
for (int j = 0; j < m; j++)
ans = max(ans, cal(0, j));
cout << ans << endl;
}
題解