传送门
题目大意:
给出一组数据n,k;
是都可以找出k个字符串使得
s=a1+a2+…+ak+a(k+1) + res(ak) + …+res(a2)+res(a1)
思路:
对称寻找相同字符,将剩余补充到ak+1
代码:
#include<iostream>
using namespace std;
void solve()
{
int n,k;
cin >> n >> k;
string s;
cin >> s;
if(k == 0) {
cout << "YES" << endl;
return ;
}
if(k*2 >= n){
cout << "NO" << endl;
return ;
}
bool si = true;
int len = s.length()-1;
for(int i = 0;i < k;++i)
{
if(s[i] == s[len-i]) continue;
else {
si = false;
break;
}
}
if(si) cout << "YES" << endl;
else cout << "NO" << endl;
}
int main()
{
int t;
cin >> t;
while(t--){
solve();
}
}
题目总结:
字符串处理,思维
传送门
题目大意:
在一串数组中找到第一个没有出现的自然数和数组最大数
然后插入[a+b]/2向上取整,可以插入k次
思路:
如果是一个自然序列,则输出n+k;
否则判断第一个数字是否可以插入
输出n+1或者n
代码
#include<bits/stdc++.h>
using namespace std;
set<int> s;
void solve()
{
int n,k;
cin >> n >> k;
s.clear();
int m = 0,ma = 0;
for(int i = 0,x;i < n;++i)
{
cin >> x;
s.insert(x);
ma = max(x,ma);
}
int cnt = 0;
bool si = true;
for(set<int>::iterator it = s.begin();it != s.end();++it,++cnt){
if(*it != cnt) {
m = cnt;
si = false;
break;
}
}
if(k == 0) {
cout << n << endl;
return ;
}
if(m == 0 && si) {
cout << n+k << endl;
return ;
}
int l = (m+ma+1)/2;
if(s.find(l) != s.end()){
cout << n << endl;
}
else cout << n+1 << endl;
}
int main()
{
int t;
cin >> t;
while(t--){
solve();
}
}
题目总结:
第一题分成一类情况,
第二题分成两类情况。
传送门
题目大意:
给n个x轴和y轴上的点,将所有点x,y 一对一 连接
求所有线长度之和的最小值
思路:
数据大的x,y和依次连接
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
long long a[maxn],b[maxn];
void solve() {
int n;
cin >> n;
int c1 = 0,c2 = 0;
for(int i = 1,x,y;i <= 2*n;++i){
cin >> x >> y;
if(x == 0) a[c1++] = fabs(y);
else b[c2++] = fabs(x);
}
sort(a,a+n);
sort(b,b+n);
double ans = 0.0;
for(int i = 0;i < n;++i){
ans += sqrt(a[i]*a[i] + b[i]*b[i]);
}
printf("%.15lf\n",ans);
}
int main() {
int t;
cin >> t;
while(t--) solve();
return 0;
}
题目总结:
思维+数学
传送门
题目大意:
小鱼和zy。
小鱼喜欢向相邻且比它当前数字小的位置移动
zy喜欢向相邻且比它当前数字大的位置移动
小鱼和zy依次选择一个位置
问小鱼选择可以赢的位置个数
思路:
寻找最长下降连续子序列,和最长上升连续子序列
而且他们共用同一个最大值
并且最大长度唯一且取余2为1
代码:
#include<iostream>
using namespace std;
#define IO ios::sync_with_stdio(0),cin.tie(0)
const int maxn = 1e5+5;
int l[maxn],r[maxn];
int a[maxn];
int main()
{
IO;
int n;
cin >> n;
for(int i = 1;i <= n;++i) cin >> a[i];
l[1] = 1;
for(int i = 2;i <= n;++i){
if(a[i] > a[i-1]) l[i] = l[i-1]+1;
else l[i] = 1;
}
r[n] = 1;
for(int i = n-1;i > 0;--i){
if(a[i] > a[i+1]) r[i] = r[i+1] + 1;
else r[i] = 1;
}
int ma = 0;
for(int i = 1;i <= n;++i) ma = max(ma,max(l[i],r[i]));
int k = 0;
for(int i = 1;i <= n;++i) if(l[i] == ma || r[i] == ma) k++;
int ans = 0;
for(int i = 1;i <= n;++i) if(l[i] == ma && r[i] == ma) ans++;
if(k == 1 && ma%2 == 1) cout << ans << endl;
else cout << 0 << endl;
}
题目总结:
简化代码需要的变量
尽可能简化空间复杂度和时间复杂度
传送门
题目大意:
将任意的.转化成X使得所有的X只有一条路径
思路:
将1,4,7列变成X然后将2,3列之间的任意一组点连接起来
代码:
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(0),cin.tie(0)
const int maxn = 505;
char a[maxn][maxn];
void solve()
{
int n,m;
cin >> n >> m;
for(int i = 1;i <= n;++i){
cin >> (a[i]+1);
}
if(m == 1)
for(int i = 1;i < n;++i)
{
if(a[i][m] == 'X' || a[i+1][m] == 'X')
a[i][m] = a[i+1][m] = 'X';
}
for(int i = 1;i <= m;i+=3)
{
for(int j = 1;j <= n;++j)
{
a[j][i] = 'X';
}
if(i+2 > m) break;
int r = 1;
for(int j = 1;j <= n;++j)
{
if(a[j][i+1] == 'X' || a[j][i+2] == 'X') r = j;
}
a[r][i+1] = a[r][i+2] = 'X';
}
if(m%3 == 0){
for(int i = 1;i <= n;++i)
{
if(a[i][m] == 'X') a[i][m-1] = 'X';
}
}
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
cout << a[i][j];
}
cout << endl;
}
return ;
}
int main()
{
IO;
int t;
cin >> t;
while(t--) solve();
return 0;
}
题目总结:
思维+暴力
传送门
层序遍历
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn = 405;
const int mod = 998244353;
vector<int> g[maxn];
LL dis[maxn][maxn],ans[maxn][maxn],vis[maxn];
int n;
void bfs(int begin)
{
for(int i = 1;i <= n;++i) dis[begin][i] = 1e18;
queue<int> q;
q.push(begin);
dis[begin][begin] = 0;
while(!q.empty())
{
int x = q.front();
q.pop();
for(int i = 0;i < g[x].size();++i)
{
int t = g[x][i];
if(dis[begin][t] > dis[begin][x]+1){
dis[begin][t] = dis[begin][x] + 1;
q.push(t);
}
}
}
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
int m;
cin >> n >> m;
for(int i = 1;i <= m;++i){
int x,y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
for(int i = 1;i <= n;++i) bfs(i);
//cout << "QAQ1" << endl;
for(int i = 1;i <= n;++i){
//cout << "QAQ2" << endl;
for(int j = 1;j <= i;++j){
//cout << "QAQ3" << endl;
memset(vis,0,sizeof(vis));
int sx = i,tx = j;
while(sx != tx){
//cout << "QAQ4" << endl;
vis[sx] = 1;
for(int k = 0;k < g[sx].size();++k){
int t = g[sx][k];
if(dis[i][sx]+1 == dis[i][t]
&& dis[j][sx] == dis[j][t]+1 ){
sx = t;
break;
}
}
}
vis[tx] = 1;
ans[i][j] = 1;
for(int k = 1;k <= n;++k){
if(!vis[k]){
int cnt = 0;
for(int l = 0;l < g[k].size();++l){
int t = g[k][l];
if(dis[i][k] == dis[i][t]+1
&& dis[j][k] == dis[j][t]+1)
cnt++;
}
vis[k] = 1;
ans[i][j] = ans[i][j]*cnt%mod;
}
}
ans[j][i] = ans[i][j];
}
}
for(int i = 1;i <= n;++i){
for(int j = 1;j <= n;++j){
cout << ans[i][j] << " ";
}
cout << endl;
}
}