ADF是我写的…BCE是shr写的…
侵立删。
F
大水题…咕咕咕
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int a,b,c,d;
cin>>a>>b>>c>>d;
while(a>0&&c>0){
c-=b;
if(c>0)a-=d;
}
if(a>0)cout<<"Yes";
else cout<<"No";
return 0;
}
A
这个题有好几种方法
从题意来看,如果是快乐数,那么最后肯定为1,如果不是快乐数,说明最后不是一,会陷入一个死循环。
第一种做法:快慢指针。
如果快指针到达1,那么慢指针也一定到达1,如果快指针追上了慢指针,此时一定有环,说明陷入了死循环。
第二种:
用哈希判断有没有重复数字出现(unordered_map也可)
第三种:暴力500次或者1000次嘻嘻
快慢指针做法代码
#include <iostream>
using namespace std;
int CalNum(int n) {
int ans = 0;
while (n) ans += (n % 10) * (n % 10), n /= 10;
return ans;
}
bool isHappy(int n) {
int f = CalNum(n), s = n;
while (f != s) {
f = CalNum(f);
f = CalNum(f);
s = CalNum(s);
}
return f == 1;
}
int main() {
int n;
while (cin >> n) cout << (isHappy(n) ? "Yes" : "No") << endl;
return 0;
}
哈希做法
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e5 + 5;
int book[100005];
int find(int x) {
int t = (x % N + N) % N;
while (~book[t] && book[t] != x) {
t++;
if (t == N)
t = 0;
}
return t;
}
int CalNum(int &n) {
int ans = 0;
while (n) ans += (n % 10) * (n % 10), n /= 10;
n = ans;
return find(n);
}
bool isHappy(int n) {
memset(book, -1, sizeof book);
int k = find(n);
while (!~book[k]) {
book[k] = n;
k = CalNum(n);
}
return n == 1;
}
int main() {
int n;
while (cin >> n) cout << (isHappy(n) ? "Yes" : "No") << endl;
}
暴力做法
#include<iostream>
using namespace std;
int Happy(int n){
int ans = 0;
while(n) ans += (n%10)*(n%10), n/= 10;
return ans;
}
signed main(){
int n; while(cin >> n){
int T = 1000; while(T--) n = Happy(n);
if(n==1) cout << "Yes" << endl;
else cout << "No" << endl;
}
}
B
简单分析一下问题,不难发现这是NIM问题的变式
而我们知道,对于引进的SG函数有
- 可选步数为1~m的连续整数,直接取模即可,SG(x) = x % (m+1);
- 可选步数为任意步,SG(x) = x;
- 可选步数为一系列不连续的数,用GetSG()计算
之后分类讨论一下即可
#include <bits/stdc++.h>
using namespace std;
int n, ans;
int SG(int a,int b){
if(a<b) return 0;
int ans;
if(a%b==0) ans=a/b;
else{
int m=a/b+1,x=(a/b)*b;
int k=(a-x)/m;
if(k>1) ans=SG(a-k*m,b);
else ans=SG(a-m,b);
}
return ans;
}
int main() {
int a, b;
int T;
cin >> T;
while (T--) {
cin >> n;
ans = 0;
for (int i = 1; i <= n; i++) {
cin >> a >> b;
ans ^= SG(a, b);
}
if (ans)
cout << "L" << endl;
else
cout << "P" << endl;
}
return 0;
}
C
首先,我们知道回文串的顺序倒转后,与原串是一样的。
所以我们输入的字符串与倒转后的字符串求最长公共子序列,就可以获取其中的回文序列,剩下的在对应的位置补上相同的就可以构造出回文串
#include <bits/stdc++.h>
using namespace std;
const int N = 2e3 + 5;
int DP[N][N];
int LCS(string a, string b) {
int AS(a.size()), BS(b.size());
for (int i(1); i <= AS; i++)
for (int j(1); j <= BS; j++)
if (!i || !j)
DP[i][j] = 0;
else if (a[i - 1] == b[j - 1])
DP[i][j] = DP[i - 1][j - 1] + 1;
else
DP[i][j] = max(DP[i - 1][j], DP[i][j - 1]);
return DP[AS][BS];
}
void strings(string a, string &b) {
for (auto it = a.rbegin(); it != a.rend(); it++) b += *it;
}
int main() {
string a, b;
cin >> a;
strings(a, b);
cout << a.size() - LCS(a, b) << endl;
return 0;
}
D
首先,要找到最后方案中的H,设为maxH,枚举寻找方案的最小值
限制条件:躺着的人不能超过n/2,宽度尽可能小
枚举h从1到这些人中的最大高度:
1.如果一个人的wi和hi均大于maxh,则该方案不可行
2.如果某个人的h或w只有一项大于maxh,那么考虑他是否h和w互换
3.剩下的人按照wi-hi从大到小排序后贪心
借鉴博客网址:添加链接描述
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
using namespace std;
const int N=1010,maxs=1e9;
int n,w[N],h[N],mh,allw,ans=maxs;
bool cmp(const int &x,const int &y){
return w[x]-h[x]>w[y]-h[y];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d%d",&w[i],&h[i]);
mh=max(w[i],max(mh,h[i]));
allw+=w[i];
}
for(int maxh=1;maxh<=mh;maxh++){
vector<int>v;
int cnt=0,noww=allw;
for(int i=1;i<=n;i++){
if(w[i]>maxh&&h[i]>maxh){
cnt=maxs;
break;
}
else if (w[i]>maxh&&h[i]<=maxh)continue;
else if(w[i]<=maxh&&h[i]>maxh){
noww+=h[i]-w[i];
cnt++;
}
else if(w[i]>h[i])v.push_back(i);
}
if(cnt>n/2)continue;
sort(v.begin(),v.end(),cmp);
for(int i=0;i<v.size()&&cnt+i<n/2;i++)noww+=h[v[i]]-w[v[i]];
ans=min(ans,noww*maxh);
}
cout<<ans;
return 0;
}
E
考虑搜索的过程。一个显而易见的想法是用一个优先队列维护搜索的节点。每次
用代价最小的点开始进行扩展。但通过进一步观察,我们可以发现扩展的过程中
只会有两种代价,x 和 x + 1,因此这个优先队列可以用一个双端队列deque代
替。如果代价需要增加则放到队尾,否则放到队首。
#include <bits/stdc++.h>
#define x first
#define y second
#define PII pair<int, int>
using namespace std;
const int N = 310;
int dist[N][N];
bool st[N][N];
char g[N][N];
deque<PII> q;
int n, m;
int dx[] = { 0, 0, 1, -1 }, dy[] = { 1, -1, 0, 0 };
void bfs(int x, int y) {
memset(dist, 0x3f, sizeof dist);
dist[x][y] = 0;
q.push_front({ x, y });
while (q.size()) {
PII t = q.front();
q.pop_front();
for (int i = 0; i < 4; i++) {
int tx = dx[i] + t.x, ty = dy[i] + t.y;
if (tx < 0 || tx >= n || ty >= m || ty < 0)
continue;
if (g[tx][ty] == '#' && dist[tx][ty] > dist[t.x][t.y] + 1) {
dist[tx][ty] = dist[t.x][t.y] + 1;
q.push_back({ tx, ty });
} else if (g[tx][ty] == '.' && dist[tx][ty] > dist[t.x][t.y]) {
dist[tx][ty] = dist[t.x][t.y];
q.push_front({ tx, ty });
}
}
}
}
int main() {
cin >> n >> m;
int x = 0, y = 0, sx = 0, sy = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
cin >> g[i][j];
if (g[i][j] == 'S')
x = i, y = j, g[i][j] = '.';
if (g[i][j] == 'T')
sx = i, sy = j, g[i][j] = '.';
}
bfs(x, y);
cout << dist[sx][sy] << endl;
return 0;
}