A
題意好像沒什么要解釋的,照著來就行
// Problem: 積分賽
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/14450/A
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int n;
int main(){
int a, b, c, d;
cin >> n;
int maxx = -1;
int id = 1;
for(int i = 1; i <= n; i++){
cin >> a >> b >> c >> d;
int summ = b * 1 + c * 2 + d * 3;
if(summ > maxx){
id = a;
maxx = summ;
}
}
cout << id << " " << maxx;
re 0;
}
B
就是求一個極差求一個方差(全是根據題意來的)
// Problem: 資料處理
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/14450/B
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int T;
int n;
int a[1000 + 10];
int main(){
cin >> T;
while(T--){
cin >> n;
int maxx = -1;
int minn = 99999999;
int summ = 0;
for(int i = 1; i <= n; i++){
scanf("%d",a + i);
summ += a[i];
maxx = max(maxx, a[i]);
minn = min(minn, a[i]);
}
double avg = summ * 1.0 / n;
double ans = 0.0;
for(int i = 1; i <= n; i++){
ans += ((a[i] - avg) * (a[i] - avg));
}
printf("%d %.3lf\n", (maxx - minn), ans / n);
}
re 0;
}
C
裸的容斥原理
加上覆寫的減去重復算過的即可
// Problem: 涂色
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/14450/C
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int T;
ll n, m, r, c;
int main(){
cin >> T;
while(T--){
cin >> n >> m >> r >> c;
ll summ = n * m;
cout << summ - r * m - c * n + r * c << endl;
}
re 0;
}
D
這題是思維題了
按從小到大排序
如果前四個數的和比最多的那個還少,那么一定可以用最后一個的水果數來匹配前面的所有水果
如果前四個的和大于第五個,那我們就先讓前四個內部匹配使剩下的剛好等于第五個,這個時候就回到了前四個小于等于第五個的問題,這樣做顯然答案是ssum/2,
證明:假設我們不能讓前四個內部匹配, 使其剩下的和小于等于第五個,那么說明我們完成前四個的匹配操作之后,只剩下了一種水果,因為只有這樣才會導致不能繼續匹配,而根據我們的假設, 剩下的這種水果的數量是比第五個要大的,與我們最開始的規定第五個最大不符,所以不可能出現這種情況,
所以如果前四個的和比第五個要大, 那么它至少會還剩下兩種水果,這兩種還能繼續匹配然后匹配下去一定可以使最后的結果是前四個的和小于等于第五個, 我們就讓他等于第五個好了(奇數的話就多一個, 無所謂)
例如:1 2 3 4 6
用前面的往后面的去配對,最后會
// Problem: 水果盒
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/14450/D
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
ll a[10];
int main(){
ll summ = 0;
for(int i = 1; i <= 5; i++){
cin >> a[i];
summ += a[i];
}
sort(a + 1, a + 1 + 5);
ll cnt = 0;
for(int i = 1; i <= 4; i++){
cnt += a[i];
}
if(cnt < a[5]){
cout << cnt;
}
else cout << summ / 2;
re 0;
}
F
按照題意模擬即可
注意一下雨天的情況
// Problem: 運動會
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/14450/F
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int main(){
int n, a;
cin >> n >> a;
double summ = 1.0 * a;
double before = 1.0 * a;
string s;
cin >> s;
for(int i = 1; i < s.size(); i++){ // 因為第一天不管什么樣都得跑,所以直接從第二天開始
if(s[i] == 's'){
summ += (before * 1.3);
before *= 1.3;
}
else if(s[i] == 'c'){
summ += (before * 0.8);
before *= 0.8;
}
else{
if(s[i + 1] != 'r') before = 1.0 * a;
}
}
printf("%.3lf", summ);
re 0;
}
G
觀察之后我們發現,
首先,某兩個數相同就一定可以成功,這是顯然的
根據這個性質,我們只需要讓某兩個數相等即可
對于這兩個數,有兩種操作,一個同時是-1,對他們相等一定是沒有貢獻的;一個是+2一個-1,本質上是讓這兩個數的差減少3,這對答案是有貢獻的
所以說任意兩個數的差值是3的倍數是可以完成操作的
不過這時候有一點要考慮的,就是你減一的同時,另一個數的大小能不能支撐你完成這些操作
這是一定的,因為即使一個數減到頭了,你們我們可以通過減其他的兩個數來對其進行+2的操作,這樣就能增加了輪數
// Problem: 一個簡單的思維題
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/14450/G
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#include <ctime>
#define ll long long
#define re return
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int T;
int main(){
cin >> T;
int a[5];
while(T--){
cin >> a[1] >> a[2] >> a[3];
if(a[1] == a[2] || a[2] == a[3] || a[1] == a[3]){
cout << "Yes" << endl;
continue;
}
if(abs(a[1] - a[2]) % 3 == 0 || abs(a[1] - a[3]) % 3 == 0 || abs(a[2] - a[3]) % 3 == 0) cout << "Yes" << endl;
else cout << "No" << endl;
}
re 0;
}
H
首先他問我們某一段的和是不是一個t的倍數(題目中是n),那么一段和我們很自然的就聯想到前綴和了,而且我們知道,如果對每一個前綴和都進行%t處理,那么就一定會使得某些數是0(假設這個數的位置是i),那么就說明從1到i的所有的數的和都是t的倍數,那么我們也會得到有的和并不是0,而是1~(t - 1)中的數,但是不妨礙里面有相同的數,
假設 s[i] % t = x,那么我們有取余的定義可知:
s
[
i
]
/
t
=
n
?
x
即
t
?
n
+
x
=
s
[
i
]
s[i] / t = n \cdots x \\ 即t * n + x = s[i]
s[i]/t=n?x即t?n+x=s[i]
那么假設還有一個數s[j]的取余結果也是x,同理
t
?
m
+
x
=
s
[
j
]
t * m + x = s[j]
t?m+x=s[j]
兩式相減得:
t
?
n
?
t
?
m
=
s
[
i
]
?
s
[
j
]
t
?
(
n
?
m
)
=
s
[
i
]
?
s
[
j
]
t*n - t*m=s[i]-s[j]\\ t*(n-m) = s[i]-s[j]
t?n?t?m=s[i]?s[j]t?(n?m)=s[i]?s[j]
那么就可以得到:
(
s
[
i
]
?
s
[
j
]
)
/
t
=
(
n
?
m
)
?
0
(s[i]-s[j]) / t = (n - m) \cdots 0
(s[i]?s[j])/t=(n?m)?0
即:
(
s
[
i
]
?
s
[
j
]
)
%
t
=
0
(s[i]-s[j]) \% t = 0
(s[i]?s[j])%t=0
那么我們就能得到一下結論:
如果某個余數在出現過之后在它后面再次出現過,那么 [ i , j ]這個區間的和就可以是t的倍數,
所以t就是j - i了
然后遍歷一遍取最大值就好了
但是我們要反過來考慮,一個區間能不能被這個t所整除,只需要記錄最后一次這個余數出現的位置即可,這樣就可以保證每一次的長度盡可能的大
如果得到的前綴和陣列取模完之后答案為0代表什么?自然就意味著前面所有的數都是它的倍數,那么此時的長度就是i,這就是為什么許多同學190的原因,
// Problem: "Inference"
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/14450/H
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int n;
int a[1000000 + 10];
int s[1000000 + 10];
int pre[1000000 + 10]; // 存盤最后一次出現的位置
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
scanf("%d", a + i);
s[i] = (s[i - 1] + a[i] % n) % n;
pre[s[i]] = i;
}
int t = -1;
for(int i = 1; i <= n; i++){
if(s[i] == 0){
t = max(t, i);
}
else t = max(t, pre[s[i]] - i);
}
cout << t;
re 0;
}
I
中號模擬
根據題意來做就好了
// Problem: 尋找字串
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/14450/I
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int n, m, q;
string s;
char mapp[110][110];
struct node{
vector<PII> id;
}p[128]; // 記錄每次每個字母出現的位置,方便后續查找
bool find(string s){
int l = p[(int)s[0]].id.size();
int len = s.size(); //字串的長度
for (int i = 0; i < l; i++){
// 看八個方向有沒有
int x = p[(int)s[0]].id[i].x;
int y = p[(int)s[0]].id[i].y;
int num = 0; // 現在s的第幾個字符
int xx = x;
int yy = y;
// up
while(yy < n){
if(mapp[xx][++yy] == s[++num]){
continue;
}
else break;
}
if(num == len)
return 1;
//down
num = 0;
xx = x;
yy = y;
while(yy >= 0){
if(mapp[xx][--yy] == s[++num]){
continue;
}
else break;
}
if(num == len)
return 1;
//left
num = 0;
xx = x;
yy = y;
while(xx >= 0){
if(mapp[--xx][yy] == s[++num]){
continue;
}
else break;
}
if(num == len)
return 1;
// right
num = 0;
xx = x;
yy = y;
while(xx < m){
if(mapp[++xx][yy] == s[++num]){
continue;
}
else break;
}
if(num == len)
return 1;
// left + up
num = 0;
xx = x;
yy = y;
while(xx >= 0 && yy < n){
if(mapp[--xx][++yy] == s[++num]){
continue;
}
else break;
}
if(num == len)
return 1;
//left + down
num = 0;
xx = x;
yy = y;
while(xx >= 0 && yy >= 0){
if(mapp[--xx][--yy] == s[++num]){
continue;
}
else break;
}
if(num == len)
return 1;
//right + up
num = 0;
xx = x;
yy = y;
while(xx < m && yy < n){
if(mapp[++xx][++yy] == s[++num]){
continue;
}
else break;
}
if(num == len)
return 1;
//right + down
num = 0;
xx = x;
yy = y;
while(xx < m && yy >= 0){
if(mapp[++xx][--yy] == s[++num]){
continue;
}
else break;
}
if(num == len)
return 1;
}
return 0;
}
int main(){
cin >> m >> n;
for(int i = 0; i < m; i++){
scanf("%s",mapp[i]);
for(int j = 0; j < n; j++){
p[(int)mapp[i][j]].id.push_back({i, j});
}
}
cin >> q;
while(q--){
cin >> s;
if(find(s)) cout << "YES" << endl;
else cout << "NO" << endl;
}
re 0;
}
后面的三個為官方題解
I

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/275035.html
標籤:其他
上一篇:PHP設計模式—建造者模式
