今晚有比赛,先来一个模拟找找状态。
模拟出来是99名,前3题的发挥都很好,就是第4题卡了一下。
A:
看一下样例说明就发现pi是单数的线一定会两两相交,双数也是。但是这里注意要用long long ,我比赛时因为这个WA了一次。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define int long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 void solve(){ 18 int a1,a2,b1,b2; 19 a1=a2=b1=b2=0; 20 int n,m,x; 21 cin>>n; 22 FOR(i,1,n){ 23 cin>>x; 24 if(x&1)a1++;else a2++; 25 } 26 cin>>m; 27 FOR(i,1,m){ 28 cin>>x; 29 if(x&1)b1++;else b2++; 30 } 31 cout<<a1*b1+a2*b2<<'\n'; 32 } 33 signed main(){ 34 ios::sync_with_stdio(0); 35 cin.tie(0); 36 int t; 37 cin>>t; 38 while(t--)solve(); 39 RE 0; 40 }
B:
这题采用贪心的思路,让最后这个点的其中一个坐标参数尽量大,另一个不用管,也是要开 long long。
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define int long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int a[100005]; 18 signed main(){ 19 ios::sync_with_stdio(0); 20 cin.tie(0); 21 int n,s=0; 22 cin>>n; 23 FOR(i,1,n)cin>>a[i],s+=a[i]; 24 sort(a+1,a+n+1,greater<int>()); 25 int sum=0; 26 FOR(i,1,(n+1)/2)sum+=a[i]; 27 s=s-sum; 28 cout<<s*s+sum*sum; 29 RE 0; 30 }
C:
首先可以先考虑第一行的摆放方法,是一个斐波那契数列,下面再分为两种情况:
1.第一行中没有相邻的两个颜色相同,那么在这种情况下必须要确定列的摆放方法才能确定矩阵,这时有列的斐波那契的数量。
2.有两个颜色相同,这时只有一种情况。
这里注意每一个矩阵都可以将它里面的0变成1,1变成0,就又是一个对的矩阵。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define int long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int mod=1e9+7,n,m,f[100005]; 18 signed main(){ 19 ios::sync_with_stdio(0); 20 cin.tie(0); 21 cin>>n>>m; 22 f[0]=f[1]=1; 23 FOR(i,2,max(n,m))f[i]=(f[i-1]+f[i-2])%mod; 24 cout<<(f[n]+f[m]-1)*2%mod; 25 RE 0; 26 }
D:
一般easy这个题目当中都有暴力这个标签,这题也是。
其实在这里n<=500可以枚举交换的两个位置,因为这里常数不大,所以能过。
每次再对整个序列取一下在什么时候")"的数量减去"("的数量的值最小,最后正确的点都是在每次达到最小值的字符与下一个字符之间截开。
首先这样做可以保证选出的正确点不会错,也能保证剩下的点都不是正确的点。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define ll long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int n;char c[505]; 18 int main(){ 19 scanf("%d%s",&n,c+1); 20 int s=0; 21 FOR(i,1,n)if(c[i]==')')s--;else s++; 22 if(s){ 23 cout<<"0 1 1";RE 0; 24 } 25 int ans=-10,ans1,ans2; 26 FOR(i,1,n){ 27 FOR(j,i,n){ 28 swap(c[i],c[j]); 29 int mini=0,sum=0; 30 FOR(k,1,n){ 31 if(c[k]==')')s--;else s++; 32 mini=min(mini,s); 33 } 34 FOR(k,1,n){ 35 if(c[k]==')')s--;else s++; 36 if(s==mini)sum++; 37 } 38 if(sum>ans){ 39 ans=sum; 40 ans1=i;ans2=j; 41 } 42 swap(c[i],c[j]); 43 } 44 } 45 cout<<ans<<'\n'<<ans1<<' '<<ans2; 46 RE 0; 47 }