比赛链接:https://ac.nowcoder.com/acm/contest/43844
思路:暴力枚举。我们只需要枚举这个点位的周围位置是否等于自己本身即可
代码:
- #include
- #define int long long
- using namespace std;
- const int N=10;
- char a[N][N];
-
- inline void solve(){
- for(int i=1;i<=4;i++)
- for(int j=1;j<=4;j++)
- cin>>a[i][j];
- bool ok=false;
- for(int i=1;i<=3;i++)
- for(int j=1;j<=3;j++)
- if(a[i][j]==a[i][j+1]&&a[i][j]==a[i+1][j+1]&&a[i][j]==a[i+1][j])
- ok=true;
- if(ok) cout<<"Yes\n";
- else cout<<"No\n";
- }
-
- signed main(){
- int T;cin>>T;
- while(T--) solve();
- }
思路:根据题意发现,第一种情况是字符串中不存在'1'的情况,第二种情况是字符串中不存在'0'的情况。所以直接暴力枚举统计两种情况的最大值,最终取最大值即可。
代码:
- #include
- using namespace std;
- const int N=2e5+10;
- char s[N];
-
- inline void solve(){
- int n;cin>>n>>s+1;
- int res=0,cnt=0;
- for(int i=1;i<=n;i++){
- if(s[i]=='1') cnt=0;
- else cnt++,res=max(res,cnt);
- }
- cnt=0;
- for(int i=1;i<=n;i++){
- if(s[i]=='0') cnt=0;
- else cnt++,res=max(res,cnt);
- }
- cout<
"\n"; - }
-
- int main(){
- int T;cin>>T;
- while(T--) solve();
- }
思路:这里选择用set容器进行存放数据。存放符合条件的数据,最后输出即可。
代码:
- #include
- #define int long long
- using namespace std;
- int val=9223372036854775807;//2^64-1
- int l,r,k;
-
- inline void solve(){
- set<int>res;
- cin>>l>>r>>k;
- int t=1;
- if(l<=t and t<=r) res.insert(t);
- for(int i=1;i<64;i++){
- if(k==0 or t<=val/k){
- t*=k;
- if(l<=t and r>=t) res.insert(t);
- }
- else break;
- }
- if(res.size()){
- for(auto x:res) cout<
" "; - }
- else cout<<"None.";
- cout<<"\n";
- }
-
- signed main(){
- int T;cin>>T;
- while(T--) solve();
- }
思路:模拟。对每一次落棋进行判断,如果达到连棋子数,输出棋子数。否则再判断下次落棋。
代码:
- #include
- using namespace std;
- const int N = 1e3+10;
- int board[N][N]; // 0--空白格 1--黑棋子 2--白棋子
- int cnt[N];
- int n,m,k,t;
- bool pd(int row,int col){//判断连棋子数
- int type=board[row][col];
- // up & down
- {
- int num1=0,num2=0;//num1:上边 num2:下边
- int i=row;
- while(i>=1&&board[i][col]==type) i--,num1++;
- i=row;
- while(i<=n&&board[i][col]==type) i++,num2++;
- if(num1+num2-1>=k) return true;
- }
- // left & right
- {
- int num1=0,num2=0;//num1:左边 num2:右边
- int i=col;
- while(i>=1&&board[row][i]==type) i--,num1++;
- i=col;
- while(i<=m&&board[row][i]==type) i++,num2++;
- if(num1+num2-1>=k) return true;
- }
- // (\)斜边
- {
- int num1=0,num2=0;//num1:左上 num2:右下
- int i=row,j=col;
- while(i>=1&&i<=n&&j>=1&&j<=m&&board[i][j]==type) i--,j--,num1++;
- i=row,j=col;
- while(i>=1&&i<=n&&j>=1&&j<=m&&board[i][j]==type) i++,j++,num2++;
- if(num1+num2-1>=k) return true;
- }
- //(/)斜边
- {
- int num1=0,num2=0;//num1:右上 num2:左下
- int i=row,j=col;
- while(i>=1&&i<=n&&j>=1&&j<=m&&board[i][j]==type) i--,j++,num1++;
- i=row,j=col;
- while(i>=1&&i<=n&&j>=1&&j<=m&&board[i][j]==type) i++,j--,num2++;
- if(num1+num2-1>=k) return true;
- }
- return false;
- }
-
- int main(){
- cin>>n>>m>>k>>t;
- for(int i=1;i<=t;i++){
- int col;cin>>col;
- int type;
- if(i&1) type=1;
- else type=2;
- int row=++cnt[col];//判断某列上第i行的棋子
- board[row][col]=type;
- if(pd(row,col)) {
- cout<
- return 0;
- }
- }
- }
E:弹珠碰撞
思路:经典模型:《碰撞==穿过》
我们发现:这里的碰撞就可以理解为穿过,题意所说:碰撞后会停止一秒,那么这里可以理解为,穿过后增加一秒。
所以这个题,我们也是同样的处理方式。
至于停顿时间,例如下图绿球,停顿的时间等于右边红球的数量。
代码:
- #include
- #define int long long
- using namespace std;
- const int N=2e6+10;
- int n,m;
- int d[N],p[N],dir[N];//dir:代表方向
-
- inline void solve(){
- cin>>n>>m;
- for(int i=1;i<=m;i++) cin>>d[i];
- for(int i=1;i<=m;i++) cin>>p[i],dir[p[i]]=d[i]+1;//使1代表左边,2代表右边
- // 1 <------- 2 ------->
- int l=0,r=0,ans=0;
- for(int i=1;i<=n;i++){
- if(dir[i]==0) continue;
- if(dir[i]==1) ans=max(ans,i+r);// <---------向左
- else r++;
- }
- for(int i=n;i>=1;i--){
- if(dir[i]==0) continue;
- if(dir[i]==2) ans=max(ans,n-i+1+l);// ------->向右
- else l++;
- }
- cout<
"\n"; - }
-
- signed main(){
- solve();
- }
对于这道题的更好解释,可以看ygg的blog:https://zhuanlan.zhihu.com/p/578344284
F: 困难卷积
思路:这里有个 trick
若 ∑a=n ,则数组 a 中不同的不超过 sqrt(n) 个。因为1+2+3+..=n,相加的个数不会超过sqrt(n)个。(就不证明了)
题目有个限制: ∑ai,∑bi<=1e7。根据结论:∑ai,∑bi的时间复杂度为sqrt(1e7) x sqrt(1e7)=1e6,所以暴力并不会TLE。直接暴力即可。
代码:
- #include
- #define int long long
- using namespace std;
- const int N=2e6+10;
- int n;
- int a[N],b[N];
- map<int,int>mp1,mp2;
-
- inline void solve(){
- cin>>n;
- for(int i=1;i<=n;i++) cin>>a[i],mp1[a[i]]++;
- for(int i=1;i<=n;i++) cin>>b[i],mp2[b[i]]++;
- int ans=0;
- for(auto[lx,ly]:mp1){
- for(auto[rx,ry]:mp2){
- ans+=(int)(sqrt(abs(lx-rx)))*ly*ry;
- }
- }
- cout<
"\n"; - }
-
- signed main(){
- solve();
- }