这次比赛6/13,可惜可惜,差一题就达到既定目标,自身思想出了问题,没🧠没♥
百思不得正解,于是开始暴力,直接DFS,发现直接超时。赛后看人代码,发现五重循环,其实就是扩展,层层遍历元素然后作出相应操作最后判定有没有结果,%%%代码。学会了新的暴力手法。
#include <bits/stdc++.h>
using namespace std;
set<long long> s[13];
int main() {
long long x, y, z;
int q;
scanf("%lld%lld%lld%d",&x,&y,&z,&q);
s[0].insert(0);
for (int i = 1; i <= 12; ++i) {
for (auto it:s[i - 1]) {
s[i].insert(it + x);
s[i].insert(it - x);
s[i].insert(it + y);
s[i].insert(it - y);
s[i].insert(it + z);
s[i].insert(it - z);
}
}
long long st = 0, d;
while (q--) {
long long ed;
scanf("%lld", &ed);
d = ed - st;
if (s[12].count(d)) {
puts("YES");
st = abs(d);
} else {
st = 0;
puts("NO");
}
}
}
模拟,行列调换的时候细心一点就行。
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > num;
vector<int> temp;
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) {
temp.clear();
temp.resize(m);
for(int j=0;j<m;j++)
scanf("%d",&temp[j]);
num.push_back(temp);
}
long long maxn1=-1;
for(int i=0;i<n;i++) {
long long sum=0;
for(int j=0;j<m;j++) {
sum+=num[i][j];
}
maxn1=max(maxn1,sum);
}
for(int i=0;i<m;i++) {
long long sum=0;
for(int j=0;j<n;j++)
sum+=num[j][i];
maxn1=max(maxn1,sum);
}
printf("%lld\n",maxn1);
return 0;
}
只会在第一天扩展,之后不再扩张。看错题的我以为是个多源BFS当场去世......其实很简单了,直接每个点扩张上下左右四点,然后看哪个点存在两次标记即为冲突点
#include<bits/stdc++.h>
using namespace std;
char mp[105][105];
int main()
{
int n, m;
while (cin >> n >> m)
{
memset(mp, '\0', sizeof(mp));
int flag = 0;
for (int i = 1; i <= n; i++)
scanf("%s", mp[i] + 1);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (mp[i][j] == '*') {
int sum = 0;
if (mp[i][j - 1] == '#')
sum++;
if (mp[i - 1][j] == '#')
sum++;
if (mp[i + 1][j] == '#')
sum++;
if (mp[i][j + 1] == '#')
sum++;
if (sum >= 2)
{
flag = 1; printf("%d %d\n", i, j);
}
}
}
}
if(flag==0)
printf("-1\n");
}
return 0;
}
又是一道二分求解最大最小值,又是莫名原因写挂,我当时直接套的板子啊,不说了%%%代码就完事了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6 + 100;
int n,m;
int a[N];
int cal(int rate)
{
int t = 0;
for(int i = 1;i <= n;i ++){
t += a[i] / rate;
if(a[i] % rate) t ++;
}
return t;
}
int main()
{
scanf("%d%d",&n,&m);
int _max = -1;
for(int i = 1;i <= n; i ++)
scanf("%d",&a[i]),_max = max(_max,a[i]);
int low = 1,high = _max, _min = _max;
while(low <= high){
int mid = (low + high)>>1;
int res = cal(mid);
if(res > m) low = mid + 1;
else{
_min = min(_min,mid);
high = mid - 1;
}
}
printf("%d\n",_min);
return 0;
}
这题目拿了一血,嘿嘿嘿,签到题写的快混了个一血
#include<bits/stdc++.h>
using namespace std;
vector<int> p;
int main() {
int n;
while(~scanf("%d",&n)) {
p.resize(n);
for(int i=0;i<n;i++) {
scanf("%d",&p[i]);
}
sort(p.begin(),p.end());
cout<<p[n-2]<<" "<<p[1]<<endl;
}
return 0;
}
语文差题意都没怎么看懂,不会待补
这个毫无思路,待补
2019CCPC网络赛的签到题,分块递归打表都可以,直接上代码了
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1024;
char A[maxn][maxn];
void Build (void) {
A[0][0] = '1';
A[0][1] = '1';
A[1][0] = '1';
A[1][1] = '0';
for (int k = 2; k <= 10; k++) {
int a = 1 << (k - 1);
int b = (1 << k) - 1;
for (int i = 0; i <= a - 1; i++)
for (int j = a; j <= b; j++)
A[i][j] = A[i][j - a];
for (int i = a; i <= b; i++)
for (int j = 0; j <= a - 1; j++)
A[i][j] = A[i - a][j];
for (int i = a; i <= b; i++)
for (int j = a; j <= b; j++)
A[i][j] = A[i - a][j - a] == '1' ? '0' : '1';
}
}
int main () {
Build();
int kase,k;
scanf("%d",&kase);
while (kase--) {
scanf("%d",&k);
k--;
int n=(1 << k) - 1;
for (int i=0;i<=n;i++) {
for (int j=n;j>=0;j--) {
printf("%c",A[i][j]);
if(j!=0)
printf(" ");
}
printf("\n");
}
}
return 0;
}
其实是二进制,数二进制数中有多少个1,就挂几个灯笼。这题也是个一血,嘿嘿嘿
#include<bits/stdc++.h>
using namespace std;
int main() {
long long k;
while(~scanf("%lld",&k)){
int cnt=0;
while(k) {
if(k%2==1)
cnt++;
k/=2;
}
printf("%d\n",cnt);
}
return 0;
}
比赛的时候觉得这种问题一般和最长上升子序列的长度或者最长下降子序列的长度,然后白给,果断放了。赛后一看其实就是求一个最长连续的子序列。👴🤮,可惜可惜
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int a[N],f[N];
inline int read() {
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
int main() {
int T,n;
T=read();
while(T--) {
n=read();
for(int i=1;i<=n;i++) {
a[i]=read(),f[a[i]]=0;
}
int ans=0;
for(int i=1;i<=n;i++) {
f[a[i]]=f[a[i]-1]+1;
ans=max(ans,f[a[i]]);
}
printf("%d\n",n-ans);
}
return 0;
}
并查集+map映射,模板题吧,没什么说的,贴了模板就A了
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1011;
const int MAX_N=1021;
struct node{
bool vis[11];
};
struct node T[MAXN];
int par[MAX_N];
int rank1[MAX_N];
void init(int n)
{
for(int i=0;i<=n;i++)
{
par[i]=i;
rank1[i]=0;
}
}
int find(int x)
{
if(par[x]==x)
return x;
else
{
return par[x]=find(par[x]);
}
}
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)
return;
if(rank1[x]<rank1[y])
par[x]=y;
else
{
par[y]=x;
if(rank1[x]==rank1[y])
rank1[x]++;
}
}
bool same(int x,int y)
{
return find(x)==find(y);
}
int main() {
int t;
while(~scanf("%d",&t)) {
while(t--) {
memset(T,false,sizeof(T));
int n;
scanf("%d",&n);
init(n);
for(int i=0;i<n;i++) {
string s;
cin>>s;
for(int j=0;j<s.length();j++)
T[i].vis[s[j]-'0']=true;
}
for(int i=0;i<n;i++) {
for(int j=i+1;j<n;j++) {
for(int k=0;k<=9;k++) {
if(T[i].vis[k]==true&&T[j].vis[k]==true) {
unite(i,j);
break;
}
}
}
}
int cnt=0;
for(int i=0;i<n;i++) {
if(par[i]==i)
cnt++;
}
printf("%d\n",cnt);
}
}
return 0;
}
不会再见,待补
又是一个假博弈,看数据范围可以打表,当瓶子剩余容量为00 时,此时要倒水的人必输,往后递推,如果有人可以倒完水之后达到必输点,那么此点为必赢点,如果没办法倒完水之后达到必输点,则此点也为必输点。然后一直往后递推。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=5011;
bool vis[MAXN];
vector<int> p;
int main() {
int n,m;
scanf("%d%d",&n,&m);
p.resize(m);
for(int i=0;i<m;i++)
scanf("%d",&p[i]);
for(int i=0;i<=n;i++) {
if(!vis[i]) {
for(int j=0;j<m;j++)
vis[i+p[j]]=true;
}
}
if(vis[n])
puts("Y");
else
puts("N");
return 0;
}
本文回顾了一场比赛的经历,总结了未能达成目标的原因,并详细解析了包括DFS、暴力搜索、二分查找、模拟、最长连续子序列等算法的实现代码。
1128

被折叠的 条评论
为什么被折叠?



