您的当前位置:首页正文

小v.2.0.思维题(长期更新版......)

2024-11-08 来源:个人技术集锦

   那年我双手插兜,不知道什叫做对手。

注:“ * ” 表示难度等级,星级越高,题目越难。

1.分赃(*) 

你别管拿的过程中到底拿几颗糖,到底最优策略是怎么样的,总之两个人clx先拿,然后yxy再拿,在每一轮拿的组合可以是(1,1),(1,3),(3,3),(3,1),每轮无论怎么拿都是偶数,以一个偶数为周期进行分糖果,管它糖果数%2也好,%4也好,%6也好,最终都和%2是一样性质的,结果也是一样的,所以正确代码如下:

​
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	string n;cin>>n;
	ll sum=(ll)n[n.length()-1];
	if(sum%2!=0)cout<<"clx";
	else cout<<"yxy";
	return 0;
}

​

2.装备二选一(*) 

​
#include<bits/stdc++.h>
using namespace std;
long int a,b,c,d;
const long int N=1e5;
int main(){
//假设普通攻击为1,不管普通攻击是多少,比较的实质也还是sum1,sum2
    cin>>a>>b>>c>>d;
    long int sum1=N*a*b+(N-N*a);
    long int sum2=N*c*d+(N-N*c);
    if(sum1>=sum2)
        cout<<"NO";
    else cout<<"YES";
    return 0;
}

​

3.追寻光的方向 (***)

 

​
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
int main(){
    ll n;
    cin>>n;
    ll i,j;
    vector<ll> a(n);
    for(i=0;i<n;i++) cin>>a[i];
    ll sum=0,max=0;
    for(i=n-1;i>0;i--){
        if(a[i]>=max){
            max=a[i];
            sum++;
        }
    }
    cout<<sum-1;
    return 0;
}

​

 

4.日历游戏 (***)

​
#include<bits/stdc++.h>
using namespace std;
int main(){
    int T;
    cin>>T;
    int x,y,z;
    while(T--){
        cin>>x>>y>>z;
        if(((y==9||y==11)&&z==30)||(y+z)%2==0) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}

​

疑问解答一:这样的操作是非法的,我们不允许这样做。题目没有对非法之后该怎么办做出解释,

 下面我们来看一张图。

这是有规律可寻得,日期变化也是有规律的,在9,11月这两天总是出错,无论是闰年还是平年,9,11月都是30天,只要保证这两个日期是是正确的,就可以合法继续操作,让Alice 保持“先手”的状态,因为操作的周期是偶数2,只要让操作次数为偶数即可保证Alice胜出。 

 5.聪明狡猾的恶魔(**)

​
#include<iostream>
using namespace std;
int main(){
    int t;
    cin>>t;
    int x,n,i;
    int money;
//一半数量的的恶魔有钱就行了,在这一半的恶魔中,恶魔一人一个金币,剩下的金币全是恶魔老大的就行了
    for(i=1;i<=t;i++){
        cin>>x>>n;
        if(n%2==0){
            money=x-(n/2-1);
        }else{
            money=x-(n/2);
        }
        cout<<money<<endl;
    }
    return 0;
}

​

6.(我的第二篇博文,2024年七夕节比赛里面有较多的思维题,解释比较详细,可自行翻阅) 

7.生日蛋糕(***) 

 

 8.吃糖果(****)

 

 

9.假金币(****) 

#include<stdio.h>   
#include<math.h> 
int main()  
{  
	int n;  
	scanf("%d",&n);
	long long num;
	for(int i=1;i<=n;i++)
	{  
		scanf("%lld",&num);
		printf("%.lf\n",ceil(log(num*1.0)/log(3.0))); //这个式子很精妙,大家可以去慢慢试一下 
	}  
}

10.Cube(****) 

 

 距离的平方比是1:2:3,避免了开根号,避免了精度问题

#include<bits/stdc++.h>
using namespace std;

int x[10], y[10], z[10];
int t[80], cnt;

int main(){
    int T;  cin>>T;
    while(T--){
        for(int i = 1; i <= 8; i++)cin>>x[i]>>y[i]>>z[i];
        cnt = 0;
        for(int i = 1; i <= 8; i++){
            for(int j = i+1; j <= 8; j++){
                t[++cnt] = (x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i])+(z[j]-z[i])*(z[j]-z[i]);
            }
        }
        sort(t+1,t+cnt+1);
        if(t[1]==t[12] && (t[1]!=0) && t[13]==t[24] && t[13]==2*t[1] && t[25]==t[28] && t[25]==3*t[1]){
            cout<<"YES\n";
            continue;
        }
        cout<<"NO\n";
    }
    return 0;
}

11.王子爱公主(***) 

 

王子需要确定公主的位置就要考虑最坏情况:随意派说的都是假话。所以支持派的人数要大于反对派加随意派的人数之和才能确定公主的位置,否则不能确定公主的位置)

王子如何确定公主:首先如果a>b+c,先询问2*(b+c)个问题,最坏情况是说假话的有b+c个人都说在i号房间,说真话的有b+c个人说在j号房间(i不等于j),此时还需要问一次(此时只剩下说真话的人),下一个人说在j号房间,此时公主就一定在j号房间

 12.Game Theory(***)

13.String Freshman(***) 

 

当时还以为有t个样例,当时就算只写了ll t;cin>>t;这一行也通不过题目。 


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    //ll t;cin>>t;这行不可写,不然就错
    
        ll m;cin>>m;
        string s;cin>>s;
        ll i;
        for(i=1;i<m;i++){
            if(s[i]==s[0]){
                cout<<"Wrong Answer"<<endl;
                return 0;
            }
        }
        cout<<"Correct"<<endl;
    return 0;
}

14.fair distribution (*****)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    ll t;cin>>t;
    while(t--){
        ll n,m;cin>>n>>m;
        if(n>m)cout<<n-m<<endl;
        else{
            ll i,j,r;
            ll ans=1e18;//注意ans的初始值
            for(i=1;r,i<=n;i=r+1){
                r=min(n,(m-1)/((m-1)/i));
                ans=min(ans,(m-1)/i*i);
            }
            cout<<ans+n-m<<endl;///n-m别忘了
        }
    }
    return 0;
}

 

疑问如下 :

15. Darkness I(*****)

 

  

16. Dice Game(*****)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=998244353;
ll qsm(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1){
            ans=ans*a%N;
        }
        a=a*a%N;
        b>>=1;
    }
    return ans;
}
ll v(ll a){
    return qsm(a,N-2);
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll n,m;cin>>n>>m;
    for(ll i=1;i<=m;i++){
        ll res=qsm((m-i)*v(m-1)%N,n);
        cout<<res<<" ";
    }
    return 0;
}

公式推导如下: 

 

17.Life is Hard and .......(*****) 

 

18.Hot Port(*****) 

(这个错题还没看哈,先放这里了下次更新,晚上了时间有点不够了) 

19.Rock Paper Scissors(****)

宝宝要分低点,网格要分高点,大概9场比赛就可以完事 ,三局胜,三局平,三局败,每局把该消耗掉的手势都消耗掉,同时计分就可以了,前三局网格一直赢,中间三局两人打一下平局,最后三局,虽然说让网格的分尽量最高,但不乏有输的情况。

数据前移代码 

#include<iostream>
using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		long long sum=0;
		long long a[3];
		long long b[3];
		cin>>a[0]>>a[1]>>a[2];
		cin>>b[2]>>b[0]>>b[1];
		//当时这么写输入是为了后面写赢的情况的时候能方便一点
		//但是事实上并不会方便多少,后面另外两种情况还是得换回来
		for(long long i=0;i<3;i++)//赢的情况
		{
			if(b[i]>=a[i]){
				sum+=a[i];
				b[i]-=a[i];
				a[i]=0;
			}else{
				sum+=b[i];
				a[i]-=b[i];
				b[i]=0;
			}
		}
		
		long long x=b[2];b[2]=b[1];b[1]=b[0];b[0]=x;///下面有解析
		for(long long i=0;i<3;i++){//打平的情况
			if(b[i]>=a[i]){
				b[i]-=a[i];
				a[i]=0;
			}else{
				a[i]-=b[i];
				b[i]=0;
			}
		}
		
		for(long long i=0;i<3;i++)//输的情况
		{
			sum-=b[i];
		}
		cout<<sum<<endl;
	}
	return 0;
}

数据后移代码(我的代码) 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	ll t;cin>>t;
	while(t--){
		vector<ll> a(3),b(3);
		cin>>a[0]>>a[1]>>a[2];
		cin>>b[2]>>b[0]>>b[1];
		ll i,j;
		ll sum=0;
		for(i=0;i<3;i++){
			if(a[i]>=b[i]){
				sum+=b[i];
				a[i]-=b[i];
				b[i]=0;
			}else{
				sum+=a[i];
				b[i]-=a[i];
				a[i]=0;
			}
		}
		for(i=0;i<3;i++){
			if(a[0]>=b[0]){
				a[0]-=b[0];
				b[0]=0;
			}else{
				b[0]-=a[0];
				a[0]=0;
			}
		}
		ll x=a[2];
		a[2]=a[1],a[1]=a[0],a[0]=x;///数据后移
		for(i=0;i<3;i++){
			if(a[i]<=b[i]){
				sum-=a[i];
				a[i]=0;
			}else{
				sum-=b[i];
				b[i]=0;
			}
		}
		cout<<sum<<endl;
	}
	return 0;
}

Our story is not over.......(未完待续) 

Top