A-POJ3414
一开始看到这题往贪心方向考虑,然后向后推导推出了一个类似约瑟夫环的问题,有点处理不了,最后放弃了这题,浪费了一个多小时的时间
这道题的正解是BFS+路径记忆回溯,对于当前状态可以考虑所有可以向后延伸的状态,即FILL(1), FILL(2) ,DROP(1), DROP(2) ,POUR(1,2), POUR(2,1)是否具有可行性,可行即送入队列,并记录其上一状态情况。
路径的输出需要从终点开始回溯,逐级向上寻找上一状态。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
#define int long long
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int HASH=131;
int a,b,k;
struct node
{
int a_now;
int b_now;
int pre_a;
int pre_b;
int state;//1 2 3 4 5 6
//FILL(1) FILL(2) DROP(1) DROP(2) POUR(1,2) POUR(2,1)
int step;//记录答案步数及判断该点是否经过
}path[200][200];
void print(int a,int b)
{
if(path[a][b].a_now==0&&path[a][b].b_now==0)
{
return;
}
print(path[a][b].pre_a,path[a][b].pre_b);
if(path[a][b].state==1)
{
cout<<"FILL(1)"<<endl;
}
else if(path[a][b].state==2)
{
cout<<"FILL(2)"<<endl;
}
else if(path[a][b].state==3)
{
cout<<"DROP(1)"<<endl;
}
else if(path[a][b].state==4)
{
cout<<"DROP(2)"<<endl;
}
else if(path[a][b].state==5)
{
cout<<"POUR(1,2)"<<endl;
}
else if(path[a][b].state==6)
{
cout<<"POUR(2,1)"<<endl;
}
}
void bfs(node t)
{
queue<node> q;
q.push(t);
while(!q.empty())
{
node tmp=q.front();
q.pop();
if(tmp.a_now==k||tmp.b_now==k)
{
cout<<tmp.step<<endl;
print(tmp.a_now,tmp.b_now);
return;
}
node v;
v.pre_a=tmp.a_now;
v.pre_b=tmp.b_now;
v.step=tmp.step+1;
if(tmp.a_now!=a)//FILL(1)
{
v.state=1;
v.a_now=a;
v.b_now=tmp.b_now;
if(path[v.a_now][v.b_now].step==0)
{
q.push(v);
path[v.a_now][v.b_now]=v;
}
}
if(tmp.b_now!=b)//FILL(2)
{
v.state=2;
v.a_now=tmp.a_now;
v.b_now=b;
if(path[v.a_now][v.b_now].step==0)
{
q.push(v);
path[v.a_now][v.b_now]=v;
}
}
if(tmp.a_now)//POUR(1)
{
v.state=3;
v.a_now=0;
v.b_now=tmp.b_now;
if(path[v.a_now][v.b_now].step==0)
{
q.push(v);
path[v.a_now][v.b_now]=v;
}
}
if(tmp.b_now)
{
v.state=4;
v.a_now=tmp.a_now;
v.b_now=0;
if(path[v.a_now][v.b_now].step==0)
{
q.push(v);
path[v.a_now][v.b_now]=v;
}
}
if(tmp.a_now&&tmp.b_now!=b)
{
v.state=5;
if(tmp.a_now+tmp.b_now>=b)
{
v.b_now=b;
v.a_now=tmp.a_now+tmp.b_now-b;
}
else
{
v.a_now=0;
v.b_now=tmp.a_now+tmp.b_now;
}
if(path[v.a_now][v.b_now].step==0)
{
q.push(v);
path[v.a_now][v.b_now]=v;
}
}
if(tmp.a_now!=a&&tmp.b_now)
{
v.state=6;
if(tmp.a_now+tmp.b_now>=a)
{
v.a_now=a;
v.b_now=tmp.a_now+tmp.b_now-a;
}
else
{
v.a_now=tmp.a_now+tmp.b_now;
v.b_now=0;
}
if(path[v.a_now][v.b_now].step==0)
{
q.push(v);
path[v.a_now][v.b_now]=v;
}
}
}
cout<<"impossible"<<endl;
}
signed main()
{
cin>>a>>b>>k;
memset(path,0,sizeof(path));
bfs(path[0][0]);
return 0;
}
B-CF-1144F
比赛的时候往贪心方向考虑,进行结构体排序,直接输出路径,wa了之后还感觉自己贪心贪得贼正确。。。
现在想起来感觉挺离谱的
二分图判断,对所给连通图进行bfs或dfs染色判断即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
#define int long long
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int HASH=131;
vector<int> v[maxn*2];
int sign=0;
struct edge
{
int x,y;
}e[maxn];
int vis[maxn];
void dfs(int st)
{
for(int i=0;i<v[st].size();i++)
{
if(vis[v[st][i]]==0)
{
if(vis[st]==1)
vis[v[st][i]]=-1;
else vis[v[st][i]]=1;
dfs(v[st][i]);
}
else if(vis[v[st][i]]==vis[st]) sign=1;
}
}
signed main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
e[i].x=a;
e[i].y=b;
}
vis[1]=1;
dfs(1);
if(sign) cout<<"NO"<<endl;
else
{
cout<<"YES"<<endl;
for(int i=1;i<=m;i++)
{
if(vis[e[i].x]==1) cout<<1;
else cout<<0;
}
cout<<endl;
}
return 0;
}
C-CF1144D
找众数,对找到的众数逐渐向外扩展就能得到最终答案,比赛时没开到这题挺可惜的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
#define int long long
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int HASH=131;
map<int,int> num;
int a[maxn];
vector<int> v;
signed main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(num[a[i]]==0) v.push_back(a[i]);
num[a[i]]++;
}
int maxx=0,id=0;
for(int i=0;i<v.size();i++)
{
if(num[v[i]]>maxx)
{
maxx=num[v[i]];
id=v[i];
}
}
int k;
for(int i=1;i<=n;i++)
{
if(id==a[i])
{
k=i;
break;
}
}
cout<<n-maxx<<endl;
for(int i=k;i>1;i--)
{
if(a[i-1]<id)
cout<<1<<' ';
else
cout<<2<<' ';
cout<<i-1<<' '<<i<<endl;
}
for(int i=k;i<n;i++)
{
if(a[i+1]==id)
continue;
else if(a[i+1]<id)
cout<<1<<' ';
else cout<<2<<' ';
cout<<i+1<<' '<<i<<endl;
}
return 0;
}
D-CF1195C
简单的dp,在被A搞心态的情况下懵逼地写出来了。。。
不开long long见祖宗
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
#include <ctime>
#define int long long
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int HASH=131;
int dp[3][maxn];//
int mp[3][maxn];
int sign[3][maxn];
signed main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>mp[1][i];
}
for(int i=1;i<=n;i++)
{
cin>>mp[2][i];
}
for(int i=1;i<=n;i++)
{
dp[1][i]=max(dp[2][i-1]+mp[1][i],dp[0][i-1]+mp[1][i]);
dp[2][i]=max(dp[1][i-1]+mp[2][i],dp[0][i-1]+mp[2][i]);
dp[0][i]=max(dp[1][i-1],dp[2][i-1]);
}
cout<<max(dp[1][n],max(dp[2][n],dp[0][n]))<<endl;
}
E-CF715A
最后几秒过了,有点刺激
这道题开始没找到思路, 只是可以确定答案的表达式一定是
(
i
∗
k
)
2
−
a
n
s
i
−
1
\frac {(i*k)^2-ans}{i-1}
i−1(i∗k)2−ans
对于这个k的值开始没有想到好的办法进行寻找,就写了一发暴力,核心代码如下
for(int i=2;i<=n+1;i++)
{
int cnt=1;
while((i*i*cnt*cnt-ans)%((i-1))!=0)
{
cnt++;
}
cout<<(i*i*cnt*cnt-ans)/(i-1)<<endl;
ans=i*cnt;
}
这种写法无疑是会T的,事实上也确实T5了,
事实上这已经十分接近正确答案了,我们可以考虑
c
n
t
=
(
i
−
1
)
cnt=(i-1)
cnt=(i−1)
此时
a
n
s
=
(
i
−
1
)
∗
(
i
−
2
)
ans=(i-1)*(i-2)
ans=(i−1)∗(i−2),对
(
i
∗
i
∗
c
n
t
∗
c
n
t
−
a
n
s
)
(
i
−
1
)
\frac {(i*i*cnt*cnt-ans)}{(i-1)}
(i−1)(i∗i∗cnt∗cnt−ans)化简后发发现该答案一定是整数,满足条件,ac代码如下
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
#include <ctime>
#define int long long
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int HASH=131;
int a[maxn];
signed main()
{
int n;
cin>>n;
int ans =2;
cout<<2<<endl;
for(int i=3;i<=n+1;i++)
{
cout<<i*i*(i-1)-i+2<<endl;
ans=i*(i-1);
// cout<<"ans "<<ans<<endl;
}
return 0;
}
F-CF1397B
写过的原题
就不多赘述了,贴两份代码,一份比赛现场敲的(有点丑),一份当时补题写的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
#include <ctime>
#define int long long
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int HASH=131;
int a[maxn];
signed main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+1+n);
int ans=0;
if(n>32)
{
for(int i=1;i<=n;i++)
{
ans+=(a[i]-1);
}
}
else
{
int sign=0;
ans=inf;
for(int i=1;i<=35000;i++)
{
int tmp=0;
int base=1;
for(int j=1;j<=n;j++)
{
tmp+=fabs(a[j]-base);
base*=i;
if(base>1e15) {sign=1;break;}
}
if(sign) break;
ans=min(tmp,ans);
if(ans!=tmp) break;
}
}
cout<<ans<<endl;
}
补题代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
using namespace std;
typedef long long ll;
const int maxn=1e5+50;
const int inf=0x3f3f3f3f;
const int MOD=1e9+7;
const int HASH=131;
int main()
{
int t;
cin>>t;
int a[maxn];
ll sum=0;
ll ss=1;
for(int i=1;i<=t;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
sort(a+1,a+1+t);
ll ans=sum-t;
for(int i=2;i<=40000;i++)
{
ll tmp=0;ss=1;
int sign=1;
for(int j=1;j<=t;j++)
{
tmp+=fabs(a[j]-ss);
ss*=i;
if(ss>1e15) {sign=0;break;}
}
if(sign==0||tmp<0)
{
{printf("%lld\n",ans);break;}
}
if(ans<tmp) {printf("%lld\n",ans);break;}
else ans=tmp;
}
return 0;
}
赛况记录
A-未完成
B-未完成
C-未完成
D-WA1次(不开long long见祖宗 )
E-WA2次
F-AC
还是思维上有一些欠缺,碰到题第一反应都是贪心,然后贪出了一个貌似正确缺不能ac的思路,浪费大量的时间,还是得继续多刷题
E题最后4秒过题还是有点刺激
附contest链接