• <menu id="sssag"></menu>
  • <menu id="sssag"></menu>
  • [USACO20FEB]Equilateral Triangles P 題解

    優雅的暴力。

    設三個點為 \((i,j,k)\),則有 \(6\) 個未知數即 \(x_i,x_j,x_k,y_i,y_j,y_k\)。又因為有 \(2\) 條關于這 \(6\) 個未知數的方程 \(ij=jk,ij=ik\),所以一定能通過枚舉其中的 \(4\) 個量來求解,時間復雜度 \(O(n^4)\)。

    而這個 \(O(n^4)\) 的暴力是肉眼可見的跑不滿(


    考慮先枚舉點 \(i\),則有以下四種情況:

    解得 \(x=a,y=a-b\)。

    其中,\(a,x>0,0\le b,y \le a\)。

    解得 \(x=a,y=a-b\)。

    其中,其中,\(a,x>0,0\le b,y\le a,\color{red}b\not= 0\)。

    解得 \(x=2b-a,y=b-a\)。

    其中,\(0\le a<b,0\le x,y\)。

    解得 \(x=2b-a,y=b-a\)。

    其中,\(0\le a<b,0\le x,y,\color{red}a\not=0\)。


    注意,有些同時存在于兩種情況的狀態, 需要通過標紅的判斷去除。

    然后就能敲出以下代碼:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=310;
    inline int read(){
    	int x=0;
    	char c=getchar();
    	for(;(c^'.')&&(c^'*');c=getchar());
    	return c=='*';
    }
    bool c[maxn][maxn];
    int n,ans;
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			c[i][j]=read();
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++){
    			if(!c[i][j]) continue;
    			for(int a=0;a<=n;a++){
    				for(int b=0;b<=a;b++){
    					if(a&&i+a<=n&&j+a<=n&&i-a+b>0&&j+a+b<=n)
    						ans+=(c[i+a][j+a]&c[i-a+b][j+a+b]);
    					if(a&&b&&i-a>0&&j+a<=n&&i+a-b<=n&&j+a+b<=n)
    						ans+=(c[i-a][j+a]&c[i+a-b][j+a+b]);
    				}
    				for(int b=a+1;b<=n;b++){
    					if(i-b-b+a>0&&j+a<=n&&i-b+a>0&&j+a+b<=n)
    						ans+=(c[i-b-b+a][j+a]&c[i-b+a][j+a+b]);
    					if(a&&i+b+b-a<=n&&j+a<=n&&i+b-a<=n&&j+a+b<=n)
    						ans+=(c[i+b+b-a][j+a]&c[i+b-a][j+a+b]);
    				}
    			}
    		}
    	printf("%d\n",ans);
    	return 0;
    } 
    

    然后你會獲得 \(51pt\) 的高分。

    容易發現,代碼中搜索到了許多冗余的狀態,考慮將判斷放到循環之外:

    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=310;
    inline int read(){
    	int x=0;
    	char c=getchar();
    	for(;(c^'.')&&(c^'*');c=getchar());
    	return c=='*';
    }
    bool c[maxn][maxn];
    int n,ans;
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			c[i][j]=read();
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++){
    			if(!c[i][j]) continue;
    			for(int a=0;a<=n;a++){
    				if(a&&i+a<=n&&j+a<=n)
    					for(int b=max(a-i+1,0);b<=a&&j+a+b<=n;b++)
    						ans+=(c[i+a][j+a]&c[i-a+b][j+a+b]);
    				if(a&&i-a>0&&j+a<=n)
    					for(int b=max(i+a-n,1);b<=a&&b<=n-j-a;b++)
    						ans+=(c[i-a][j+a]&c[i+a-b][j+a+b]);
    				if(j+a<=n)
    					for(int b=a+1;j+a+b<=n&&b+b<i+a;b++)
    						ans+=(c[i-b-b+a][j+a]&c[i-b+a][j+a+b]);
    				if(a&&j+a<=n)
    					for(int b=a+1;j+a+b<=n&&b+b<=n-i+a;b++)
    						ans+=(c[i+b+b-a][j+a]&c[i+b-a][j+a+b]);
    			}
    		}
    	printf("%d\n",ans);
    	return 0;
    } 
    

    然后就過了。

    祝AC。

    posted @ 2022-03-12 22:07  欒竹清影  閱讀(0)  評論(0編輯  收藏  舉報
    国产在线码观看超清无码视频,人妻精品动漫H无码,十大看黄台高清视频,国产在线无码视频一区二区三区,国产男女乱婬真视频免费,免费看女人的隐私超爽,狠狠色狠狠色综合久久蜜芽