T1T1

题目传送门

考试错误:

已经有了这道题的思路,但是在考虑a[1]==a[n]a[1]==a[n]的时候,忽略了n==1n==1的情况。所以只拿了9595分,不过还好及时发现了,没有失分。

思路:

11.如果n==1n==1,直接输出-11returnreturn 00;

22.如果a[1]==a[n]a[1]==a[n],输出11

33.否则遍历数组,找到一个"分水岭",使得它左右两边 都能消。找到输出22,没找到输出11。 代码:

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+50;
int a[N];
int main(){
    freopen("num.in", "r", stdin);
    freopen("num.out", "w", stdout);
    int n;
    cin >> n;
    for(int i=1;i<=n;i++){
        cin >> a[i];
    }
    if(a[1]==a[n]&&n!=1){
        cout << 1;
        return 0;
    }
    for(int i=2;i<n-1;i++){
        if(a[i]==a[1]&&a[i+1]==a[n]){
            cout << 2;
            return 0;
        }
    }
    cout << -1;
    return 0;
}

T2T2

题目传送门

考试错误:不会做,骗分的,没发生错误。

不会做原因:在考试时只想到了有极大值的情况,没考虑气球数量的奇偶性带来的影响。

思路:

11.如果有一个气球的数量>>其他的气球总数量,那么输出11,returnreturn 00;

22.如果气球总数为奇数,那么任意一个气球都有可能剩下11个,输出nn,returnreturn 00;

33.如果总数为偶数。那么只要气球数 >> 11就可以留下,输出数量 >> 11的气球种类数。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+50;
int mx,ans,cnt;
int a[N];
signed main(){
   freopen("balloon.in", "r", stdin);
   freopen("balloon.out", "w", stdout);
    int n;
    cin >> n;
    for(int i=1;i<=n;i++){
    	cin >> a[i];
        mx=max(mx,a[i]);
        ans+=a[i];
        if(a[i]==1) cnt++;
	}
    if(n==2&&a[1]==a[2]) cout << 0;
    else if(mx>=ans-mx) cout << 1;
    else if(ans%2) cout << n;
    else if(ans%2==0) cout << n-cnt;
}

T3T3

题目传送门

考试错误:无,一遍ACAC的。

思路:

11.大模拟题,小的加,大的减,没什么好说的,只是代码长一点而已(100100行不长吧…)。

22.注意特判(数据不严谨,没有出,想挑战的话试试这组数据:33 11 11 00 ABAB ACACBCBC ACAC):如果 两个数都为11,则根据下一次用到的数来决定加哪个(用到那个加哪个,都用到了随便加)。

代码:

#include <bits/stdc++.h>
using namespace std;
string t;
string s;
vector<string> vctr;
int n,a,b,c;
int main(){
    freopen("game.in", "r", stdin);
    freopen("game.out", "w", stdout);
    cin >> n >> a >> b >> c;
    for(int i=1;i<=n;i++){
        cin >> s;
        vctr.push_back(s);
    }
    for(int i=0;i<vctr.size();i++){
        if(vctr[i]=="AB"){
            if(a==1&&b==1){
                if(i==vctr.size()-1){
                    t=t+"A";
                }else{
					if(vctr[i+1]=="BC"){
                        a--,b++;
                        t=t+"B";
                    }else{
                    	a++,b--;
                    	t=t+"A";
					} 
                }
            }else{
            	if(!a&&!b){
            		cout << "No";
            		return 0;
				}
            	if(a>b){
            		a--,b++;
            		t=t+"B";
				}else{
					a++,b--;
					t=t+"A";
				}
			}
        }if(vctr[i]=="BC"){
        	if(b==1&&c==1){
                if(i==vctr.size()-1){
                    t=t+"B";
                }else{
                    if(vctr[i+1]=="AC"){
                        b--,c++;
                        t=t+"C";
                    }else{
                    	b++,c--;
                    	t=t+"B";
					}
                }
            }else{
            	if(!c&&!b){
            		cout << "No";
            		return 0;
				}
            	if(b>c){
            		b--,c++;
            		t=t+"C";
				}else{
					b++,c--;
					t=t+"B";
				}
			}
        }if(vctr[i]=="AC"){
            if(a==1&&c==1){
                if(i==vctr.size()-1){
                    t=t+"A";
                }else{
                    if(vctr[i+1]=="AB"){
                        a++,c--;
                        t=t+"A";
                    }else{
                    	a--,c++;
                    	t=t+"C";
					}
                }
            }else{
            	if(!a&&!c){
            		cout << "No";
            		return 0;
				}
            	if(a>c){
            		a--,c++;
            		t=t+"C";
				}else{
					a++,c--;
					t=t+"A";
				}
			}
        }
    }
    cout << "Yes\n"; 
    for(int i=0;i<t.size();i++){
    	cout << t[i] << endl;
	}
}

T4T4

题目传送门

不会做原因:对图的理解不深刻,导致不会用标记数组的方法来做。

思路:

11.初始化:时候将标记数组全设为11

22.每次连接时判断高度,高度低的就设为00,一样就都设为00

33.最后输出所有是11的台子(仙峰台)的个数。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+20;
int a[N],st[N];
signed main(){
    freopen("penglai.in", "r", stdin);
    freopen("penglai.out", "w", stdout);
    int n,m;
    cin >> n >> m;
    for(int i=1;i<=n;i++){
        cin >> a[i];
        st[i]=1;
    }for(int i=1;i<=m;i++){
        int x,y;
        cin >> x >> y;
        if(a[x]<=a[y]){
            st[x]=0;
        }if(a[y]<=a[x]){
            st[y]=0;
        }
    }
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(st[i]) cnt++;
    }
    cout << cnt;
}

T5T5

题目传送门

考试错误:不会优化,骗分的,没发生错误。

不会做原因:在做题时没有打草稿,没有推公式,所以只能暴力骗分。

思路:

11.设aa+bbbb·gcdgcd(aa,bb)的倍数。

22.不难发现bb·gcdgcd(aa,bb)是bb的倍数,而aa+bbbb·gcdgcd(aa,bb)的倍数,所以aa+bbbb的倍数,aa也就是bb的倍数。

33.aabb的倍数,所以gcdgcd(aa,bb)=b=b。将bb·gcdgcd(aa,bb)等量代换成b2b^2,所以题目变成aa+bbb2b^2的倍数(这里用连除,防止b2b^2溢出)。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,ans;
signed main(){
    freopen("math1.in", "r", stdin);
    freopen("math1.out", "w", stdout);
    cin >> n >> m;
    for(int b=1;b<=m;b++)
        for(int a=b;a<=n;a+=b)
            if((a+b)%(b*b)==0) ans++;
    cout << ans; 
}

T6T6

不会做原因:对DPDP的理解不深,以后还要多去积累。

DP思路:

状态表示:f[i][j]:第ii天到达第jj个小屋的方案数

注意:r[i]=l[i]+s[i],且i,j,k是三重循环遍历。

状态计算:sum+=r[j]*r[k]-l[j]*l[k]*f[i-1][k]

代码:

#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
long long n,m,s[110],l[110],r[110],dp[1010][110];
bool f[100010];
int main(){
	freopen("walk.in","r",stdin);
	freopen("walk.out","w",stdout);
	cin >> m >> n;
	for(long long i=1;i<=m;i++) cin >>s[i];
		for(long long i=1;i<=m;i++){
			cin >> l[i];
			r[i]=l[i]+s[i];
	}
	dp[0][1]=1;
	for(long long i=1;i<=n;i++){
		for(long long j=1;j<=m;j++){
			long long sum=0;
			for(int k=1;k<=m;k++){
				sum+=(r[j]*r[k]-l[j]*l[k])*dp[i-1][k];
				sum%=mod;
			}
			dp[i][j]=sum;
		}
	}
	long long sum=0;
	for(long long i=1;i<=m;i++){
		sum+=dp[n][i];
		sum%=mod;
	}
	cout << sum;
	return 0;
}