2020/8/9晚上断网了,本来不想打就顺便看看题目,发现能做几个,然后就交了。(做完1、2两题才敢交)最终做了3个题tcl。
A - Suborrays
脑筋急转弯题目。位运算OR运算结果只会变大不会变小,直接正序输出就可
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{IO;int T;cin>>T;while(T--){int n;cin>>n;for(int i=1;i<=n;i++) cout<<i<<" ";cout<<endl;}return 0;
}
B - Fix You
这个题感觉比A还容易写出来。直接保证最后一行和最后一列出不去就行。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110;
int n,m;
char g[N][N];
int main()
{IO;int T;cin>>T;while(T--){cin>>n>>m;for(int i=1;i<=n;i++) cin>>g[i]+1;int res=0;for(int i=1;i<n;i++)if(g[i][m]!='D') res++;for(int j=1;j<m;j++)if(g[n][j]!='R') res++;cout<<res<<endl;}return 0;
}
C - Cyclic Permutations
正解:直接输出n!−2n−1n!-2^{n-1}n!−2n−1
歪门邪道(wtcl):无环转化一下就是两个数之间不能有一个数比他俩都小。
于是尝试构造:对于1 2 3 4…n我们发现原序列满足,逆序也满足。
1 (3 4…n ) 2 只要括号里面没有环,原序列没有环
1 2 (4 … n) 3 同样只要括号里面没有环,原序列没有环
…
只要正序无环那么逆序也无环
于是f[i]=2×(f[i−2]+f[i−3]+...+f[1])+2f[i]=2×(f[i-2]+f[i-3]+...+f[1])+2f[i]=2×(f[i−2]+f[i−3]+...+f[1])+2(+2是1 2 3…n和n … 3 2 1)
因此答案是n!−f[n]n!-f[n]n!−f[n]
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#include<iostream>
using namespace std;
typedef long long ll;
const int N=1000010,mod=1e9+7;
ll f[N];
int main()
{IO;int n;cin>>n;ll a=1;for(int i=1;i<=n;i++) a=a*1ll*i%mod;//预处理 n!f[1]=1,f[2]=3;//f[2]=2, f[2]=f[2]+f[1]=3 前缀和for(int i=3;i<=n;i++){f[i]=(2*f[i-2]%mod+2)%mod;f[i]=(f[i]+f[i-1])%mod;}cout<<((a-f[n]+f[n-1])%mod+mod)%mod<<endl;//前缀和return 0;
}
大佬:这种规律题目可以直接猜结论
D - 505
这题快写成模拟了注意:n≤mn \leq mn≤m,对于n>3n>3n>3一定不符合直接输出-1。(n>3n>3n>3考虑2×22×22×2和4×44×44×4,一个4×44×44×4肯定有四个2×22×22×2因为2×22×22×2都是奇数个1,因而4×44×44×4中一定有偶数个1)自己就想到这。
大神题解
暴力枚举每一列的状态状态压缩。
状态表示:①集合:f[i][j]
表示第i
列的状态是j
并且符合题意的集合②属性:最小值
状态计算:枚举上一列的状态k
如果i
和j
能过转移则转移f[i][j]=min(f[i][j],f[i-1][k]+calc(now^j)
now
是原数组该列的状态j
是枚举的状态,由now
->j
花费的代价为calc(now^j)
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N=1000010;
int n,m;
int a[5][N];
bool ok[10][10];
int f[N][10];
int lowbit(int x)
{return x&-x;
}
int calc(int x)
{int res=0;while(x){x-=lowbit(x);res++;}return res;
}
void init(int n)
{for(int i=0;i<1<<3;i++)for(int j=0;j<1<<3;j++){int cnt1[3];cnt1[0]=cnt1[1]=cnt1[2]=0;for(int k=0;k<3;k++){ if(i>>k&1) cnt1[k]++;if(j>>k&1) cnt1[k]++;}bool flag=1;for(int k=0;k<n-1;k++)//注意n-1if((cnt1[k]+cnt1[k+1])%2==0) flag=0;if(flag) ok[i][j]=1;}
}
int main()
{//OI;这个东西和scanf混用会出问题!!!cin>>n>>m;if(n>=4) return printf("-1\n"),0;if(n==1) return printf("0\n"),0;//神仙写法,学习了init(n);//预处理合法转移的状态 i jfor(int i=1;i<=n;i++)for(int j=1;j<=m;j++) scanf("%1d",&a[i][j]);memset(f,0x3f,sizeof f);for(int i=0;i<1<<n;i++) f[0][i]=0;for(int i=1;i<=m;i++){int now=a[1][i]+a[2][i]*2+a[3][i]*4;for(int j=0;j<1<<n;j++)for(int k=0;k<1<<n;k++)if(ok[j][k]) f[i][j]=min(f[i][j],f[i-1][k]+calc(now^j));}int res=0x3f3f3f3f;for(int i=0;i<1<<n;i++) res=min(res,f[m][i]);printf("%d\n",res);return 0;
}
要加油哦~