暑训第一次热身赛总结

1. 生成目录

B - Xenia and Weights

模拟搜索。
由于数据较小。直接搜索即可。
满足两个条件:
1.不能相同(就当相同的时候跳转)
2.设置一个差值。筛选从差值起。更新差值。
比如一个8.差值为8.那么就从8搜到10 假设搜到10那么更新差值为2.那么下一次从2开始搜。
以下为代码
#include<iostream>
#include<vector>
using namespace std;
vector<int>ans;
int coun=0;
int k[10];
int m;
int dfs(int pre,int cha,int x)
{
    if(x==m)return 1;
    for(int i=0;i<coun;i++){
        if(k[i]==pre||k[i]<=cha)continue;
        if(dfs(k[i],k[i]-cha,x+1)){
            ans.push_back(k[i]);
            return 1;
        }
    }
    return 0;
}
int main()
{
    char a[10];
    cin>>a>>m;
    for(int i=0;i<10;i++){
        if(a[i]=='1')k[coun++]=i+1;
    }
    int i;
    for(i=0;i<coun;i++) {
        if (dfs(k[i], k[i], 1)) {
            cout << "YES" << endl;
            ans.push_back(k[i]);
            for(int i=ans.size()-1;i>=0;i--){
                cout<<ans[i]<<" ";
            }
            cout<<endl;
            return 0;
        }
    }
    if(i==coun)cout<<"NO"<<endl;
}

D - Rational Resistance

当大于1很好想就是1+1+a/b(小于1)的形式(串联) 小于1时。需要利用并联去倒数的想法。其实就是1/(b/a)而b/a又可以转换为大于1的思想。关键是想到并联去倒数。 总结:结论不一定要完全退出来。学会去猜过程,限制条件,自然的算去。
#include<iostream>
using namespace std;
int main()
{
    long long a,b,coun=0;
    cin>>a>>b;
    if(a<b)swap(a,b);
    while(a&&b)
    {
        coun+=a/b;
        a=a%b;
        swap(a,b);
    }
    cout<<coun<<endl;
}

F - Mafia

每个游戏有n-1个可选择的。也就是说总共要玩的次数分给每场n-1,最多要玩的也要考虑。当最多满足时,其他的一定满足吗?没完全想明白。
#include<iostream>
#include <algorithm>
using namespace std;
int main()
{
    int n;cin>>n;
    int x;long long sum=0,maxx=-1;
    for(int i=0;i<n;i++)
    {
        cin>>x;sum+=x;
        if(x>maxx)maxx=x;
    }
    long long add=sum%(n-1)?1:0;
    cout<<max(sum/(n-1)+add,maxx)<<endl;
}

H - Qualification Rounds

很有趣的一道题。选择给出的行,使得每列有1的个数最大为总行数一半。
要点:
1.满足多个行一定满足两个行
2.两个行如果要使最大为一半,一定有一个数字为0,所以&最后结果为0那么就是答案。
3.n2暴力太大,只能通过k来暴力。也就是原本遍历行,现在遍历0-2^k-1,查找是否在给出行即可。
4.遍历i可以等于k这是刚好0这种情况(就不用特判了)
#include<iostream>
#include <set>
using namespace std;
set<int>zyx;
int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=0;i<n;i++){
        int er=0;
        for(int z=0;z<k;z++){
            int x;cin>>x;
            er=(er<<1)|x;
        }
        zyx.insert(er);
    }
    int maxn=0;
    for(int i=0;i<k;i++)
    {maxn+=(1<<i);}
    for(int i=0;i<=maxn;i++)
        for(int z=0;z<=maxn;z++){
            if(zyx.count(i)&&zyx.count(z)&&(i&z)==0)
            {cout<<"YES"<<endl;
            return 0;}
        }
    cout<<"NO"<<endl;
        return 0;
}

J - Make a Permutation!

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=200000+5;
int main()
{
    int a[maxn],vis[maxn];
    int n,i,coun;cin>>n;
    memset(vis,0, sizeof(vis));
    for(int i=0;i<n;i++){
        cin>>a[i];
        vis[a[i]]++;
    }
    i=0;
    coun=0;
    for(int k=1;k<=n;k++){
        if(vis[k]==0){
            coun++;
            while(i<n){
                if(vis[a[i]]>1||vis[a[i]]<0){
                    if(k<a[i]||vis[a[i]]<0){
                        vis[a[i]]--;
                        a[i]=k;
                        i++;
                        break;
                    }
                    if(k>a[i])vis[a[i]]=-1;
                }
                i++;
            }
        }
    }
    cout<<coun<<endl;
    for(int z=0;z<n;z++) {
        cout << a[z];
        if (z != n - 1)cout << " ";
        else cout << endl;
    }
}

O - Short Program

#include <iostream>
using namespace std;
int main()
{
    int n;cin>>n;
    char x;int k;
    int yyy=0,xxx=1023;
    for(int i=0;i<n;i++){
        cin>>x>>k;
        if(x=='|'){
            yyy|=k;
            xxx|=k;
        }
        if(x=='^'){
            yyy^=k;
            xxx^=k;
        }
        if(x=='&'){
            yyy&=k;
            xxx&=k;
        }
    }
    int op1=0,op2=0,af1,af2;
    for(int i=0;i<10/**/;i++){
        af1=yyy&(1<<i);
        af2=xxx&(1<<i);
        if(af1&&af2){
            op1|=(1<<i);
        }
        if(af1&&!af2){
            op2|=(1<<i);
        }
        if(!af1&&!af2){
            op1|=(1<<i);
            op2|=(1<<i);
        }
    }
        cout<<2<<endl;
        cout<<"|"<<" "<<op1<<endl;
        cout<<"^"<<" "<<op2<<endl;
}

K - Fire

01背包dp不解释。(可以去搜其他博客) 再写一遍
#include <iostream>
#include<string.h>
#include <algorithm>
#include<vector>
using namespace std;
const int xulie=2000+5;
int a[xulie],b[xulie],c[xulie],id[xulie],dp[xulie];
bool cmp(int a,int c){
    return b[a]<b[c];
}
int main()
{
    vector<int>path[xulie];
    int n;cin>>n;
    for(int i=0;i<n;i++)
    {cin>>a[i]>>b[i]>>c[i];id[i]=i;}
    sort(id,id+n,cmp);
    for(int k=0;k<n;k++){
        int i=id[k];
        if(a[i]>b[i])continue;
        for(int j=b[i]-1;j>=a[i];j--) {
            if (dp[j - a[i]] + c[i] > dp[j]) {

                dp[j] = dp[j - a[i]] + c[i];

                path[j].clear();
                path[j] = path[j - a[i]];
                path[j].emplace_back(i);
            }
        }
    }
    int maxx=-1;int j=0;
    for(int i=0;i<=2005;i++)
    {if(maxx<dp[i]){
            maxx = dp[i];
            j = i;
        }
    }
    cout<<maxx<<endl<<path[j].size()<<endl;

    for(int i=0;i<path[j].size();i++)
        cout<<path[j][i]+1<<" ";
}

G - Race Against Time

链接:https://vjudge.net/contest/309304#problem/G 这里其实只要模拟一下就行。我的方法先的麻烦了。虽然感觉没有逻辑问题。但是不建议再花时间去细究有什么问题(可以再写一遍) 正确代码
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
using namespace std;
int a,b,c,d,e;
int f[100];
int main()
{
    scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
    a*=5,d*=5,e*=5;
    a%=60;
    d%=60;
    e%=60;
    f[a]++;
    f[b]++;
    f[c]++;
    if(d>e) swap(d,e);
    int ans=0;
    for(int i=d;i<e;i++)ans+=f[i];
    if(ans%3==0)puts("YES");
    else puts("NO");
return 0;
}

错误代码:

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int a[5];
    for(int i=0;i<5;i++){
        cin>>a[i];
        a[i]%=60;
    }
    a[0]=a[0]*5%60;a[3]=a[3]*5%60;a[4]=a[4]*5%60;
    int f=a[3],e=a[4];
    sort(a,a+5);
    int n=unique(a, a+5)-a;
    for(int i=0;i<n;i++){
        if(a[i]==f){
            int zyx=i-1;
            if(zyx<0)zyx=n-1;
            if(a[zyx%n]==e||a[i+1%n]==e)
            {
                cout<<"YES"<<endl;
                return 0;
            }
            else cout<<"NO"<<endl;
        }

    }
}

L - Resort

链接:https://vjudge.net/contest/309304#problem/L 正确代码
#include <iostream>
#include <vector>
using namespace std;
const int maxn=1e5+5;
vector<int>edge[maxn];vector<int>path[maxn];
int k[maxn];int vis[maxn];
int n;
int x;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> k[i];
    }
    for (int i = 1; i <= n; i++) {
        cin >> x;
        if (x){edge[i].push_back(x);
        vis[x]++;}
    }
    for (int i = 1; i <= n; i++) {
        if (k[i]) {
            path[i].push_back(i);//a
            if (edge[i].size() == 0)continue;
            int pre = edge[i][0];
            while (true) {
                if (k[pre])break;//
                if (vis[pre] > 1)break;
                path[i].push_back(pre);
                if (edge[pre].size() == 0)break;
                pre = edge[pre][0];
            }
        }
    }
    int pos = 0;
    int maxx = -1;
    for (int i = 1; i <= n; i++) {
        int k=path[i].size();
        if (k > maxx) {
            maxx=k;
            pos = i;
        }
    }
    cout << maxx << endl;
    for (int i = path[pos].size() - 1; i >= 0; i--) {
        cout << path[pos][i] ;
        if(i==0){cout<<endl;}
        else cout<<" ";
    }
}

错误代码(下标0-n周末看下为什么错吧)

#include <iostream>
#include <vector>
using namespace std;
const int maxn=1e5+5;
vector<int>edge[maxn];vector<int>path[maxn];
int n;
int x;
int main() {
    cin >> n;
    int k[maxn];int vis[maxn];
    for (int i = 0; i < n; i++) {
        cin >> k[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> x;
        if (x){edge[i].push_back(x-1);
        vis[x-1]++;}
    }
    for (int i = 0; i < n; i++) {
        if (k[i]) {
            path[i].push_back(i);//a
            if (edge[i].size() == 0)continue;
            int pre = edge[i][0];
            while (true) {
                if (k[pre])break;
                if (vis[pre] > 1)break;
                path[i].push_back(pre);
                if (edge[pre].size() == 0)break;
                pre = edge[pre][0];
            }
        }
    }
    int pos = 0;
    int maxx = -1;
    for (int i = 0; i < n; i++) {
        int k=(int)path[i].size();
        if (k > maxx) {
            maxx=k;
            pos = i;
        }
    }
    cout << maxx << endl;
    for (int i = path[pos].size() - 1; i >= 0; i--) {
        cout << path[pos][i]+1 ;
        if(i==0){cout<<endl;}
        else cout<<" ";
    }
}

2. 结语

写的比较慢。很多也看了题解。其实很多都是模拟。真正用到算法就是只有背包,线段树。大部分靠思维。其实搞不懂到底是死磕到底好呢?还是看题解写快点好呢?明天问下llw吧。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值