Swust 2019级第7次周赛-赛后总结及反思

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} i1(ik)2ans
对于这个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=(i1)
此时 a n s = ( i − 1 ) ∗ ( i − 2 ) ans=(i-1)*(i-2) ans=(i1)(i2),对 ( i ∗ i ∗ c n t ∗ c n t − a n s ) ( i − 1 ) \frac {(i*i*cnt*cnt-ans)}{(i-1)} (i1)(iicntcntans)化简后发发现该答案一定是整数,满足条件,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链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值