2017 gdut学校試合の初戦の題解
25100 ワード
タイトルのソース:http://www.gdutcode.sinaapp.com/contest.php?cid=1054
Problem A:An easure problem
标准サインは问题になりますが、直接にAcceptを出力します。A大文字でない人はどのような気持ちですか?
解析:規則的なシーケンスです。公式を押していません。直接的に打つ表です。公式は(n/4+1)*5+(n%4+1)です。
二分の答え、二分の答えが出たら、二分の検索は各シーケンスの中でどれぐらいの小さいのが彼に等しくて、stlはいいものですか?
重点がないので、可能な線分は全部n*(n-1)/2です。直線ですから、二つの点を列挙して、他の点と交わるかどうかを判断します。もし交わるとans–
解析:dp問題、dp[i][n]は点iの長さがnであるかどうかを表しています。状態移行方程式は、dp[tmp.v][tt]=dp[i]、[tt-tmp.w]で、tmp.vからiまでの間にtmp.wの長さがあります。
解析:歯車ごとに所望の位置に移動する最低ステップ数は、min((Ai-ai+10)%(ai-i+10)%10です。
尺取保守の答え
解析:一点を見つけて、正方形の長さを列挙して、合法かどうかを判断する。
Problem A:An easure problem
标准サインは问题になりますが、直接にAcceptを出力します。A大文字でない人はどのような気持ちですか?
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
puts("Accept");
return 0;
}
Problem B:Tmkはスープご飯を食べます。解析:規則的なシーケンスです。公式を押していません。直接的に打つ表です。公式は(n/4+1)*5+(n%4+1)です。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 10050;
int a[maxn];
int main()
{
a[0] = 6;
for(int i=1;i1]+1;
if(i%4==0)
a[i]++;
}
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
printf("%d
",a[n]);
}
return 0;
}
Problem C:進撃の調査兵団二分の答え、二分の答えが出たら、二分の検索は各シーケンスの中でどれぐらいの小さいのが彼に等しくて、stlはいいものですか?
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5+100;
int a[maxn];
int b[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,q;
scanf("%d %d %d",&n,&m,&q);
for(int i=0;iscanf("%d",&a[i]);
for(int i=0;iscanf("%d",&b[i]);
while(q--)
{
int l1,r1,l2,r2,k;
scanf("%d %d %d %d %d",&l1,&r1,&l2,&r2,&k);
int l = min(a[l1],b[l2]),r = max(a[r1],b[r2]);
while(lint mid = l+((r-l)/2);
int pos1 = lower_bound(a+l1,a+r1+1,mid)-a;
if(a[pos1]==mid)
pos1++;
int pos2 = lower_bound(b+l2,b+r2+1,mid)-b;
if(b[pos2]==mid)
pos2++;
if(pos1+pos21;
else
r = mid;
}
printf("%d
",l);
}
}
return 0;
}
Problem D:TMKの航写画像重点がないので、可能な線分は全部n*(n-1)/2です。直線ですから、二つの点を列挙して、他の点と交わるかどうかを判断します。もし交わるとans–
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 2e5+10;
struct point
{
int x,y;
}a[maxn];
int n,m;
int x_mul(point p0,point p1,point p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int main()
{
//freopen("a.in","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=0;iscanf("%d %d",&a[i].x,&a[i].y);
int ans = n*(n-1)/2;
for(int i=0;ifor(int j=i+1;jfor(int k=0;kif(k>=i && k<=j)
continue;
if(x_mul(a[k],a[i],a[j])==0)
ans--;
}
}
}
printf("%d
",ans);
}
return 0;
}
Problem E:遠回り解析:dp問題、dp[i][n]は点iの長さがnであるかどうかを表しています。状態移行方程式は、dp[tmp.v][tt]=dp[i]、[tt-tmp.w]で、tmp.vからiまでの間にtmp.wの長さがあります。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 5000+40;
struct node
{
int v,w;
node() {}
node(int _v,int _w)
{
v = _v;
w = _w;
}
};
vector G1[maxn],G2[maxn];
int dp[maxn][maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=n;i++)
G1[i].clear(),G2[i].clear();
while(m--)
{
int u,v,l;
scanf("%d %d %d",&u,&v,&l);
if(u!=v)
{
if(u>v)
swap(u,v);
G1[u].push_back(node(v,l));
}
else
G2[u].push_back(node(v,l));
}
dp[1][0] = 1;
for(int i=1;i<=n;i++)
{
for(unsigned j=0;jfor(int tt=tmp.w;tt<=k;tt++)
dp[i][tt] |= dp[i][tt-tmp.w];
}
for(unsigned j=0;jfor(int tt=tmp.w;tt<=k;tt++)
dp[tmp.v][tt] |= dp[i][tt-tmp.w];
}
}
int ans = -1;
for(int i=0;i<=k;i++)
{
if(dp[n][i])
ans = i;
}
printf("%d
",ans);
}
return 0;
}
Problem F:パスワードロック解析:歯車ごとに所望の位置に移動する最低ステップ数は、min((Ai-ai+10)%(ai-i+10)%10です。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 10050;
int a[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int ans = 0;
while(n--)
{
int a1,b1,c1,d1;
int a2,b2,c2,d2;
scanf("%d %d %d %d",&a1,&b1,&c1,&d1);
scanf("%d %d %d %d",&a2,&b2,&c2,&d2);
ans += min((a1-a2+10)%10,(a2-a1+10)%10);
ans += min((b1-b2+10)%10,(b2-b1+10)%10);
ans += min((c1-c2+10)%10,(c2-c1+10)%10);
ans += min((d1-d2+10)%10,(d2-d1+10)%10);
}
printf("%d
",ans);
}
return 0;
}
知識は分解に由来する。尺取保守の答え
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e6+10;
char a[maxn];
int vis[100];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,k;
scanf("%s %d",a,&k);
n = strlen(a);
int ans = 0;
int l = 0,r = 0,cnt = 0;
memset(vis,0,sizeof(vis));
while(n-l>ans)
{
while(rif(vis[a[r]-'A'])
vis[a[r]-'A']++;
else
{
if(cnt+1>k)
break;
else
cnt++;
vis[a[r]-'A']++;
}
r++;
}
if(cnt == k)
ans = max(ans,r-l);
vis[a[l]-'A']--;
if(vis[a[l]-'A']==0)
cnt--;
l++;
}
printf("%d
",ans);
}
return 0;
}
Problem H:正方形を探します。解析:一点を見つけて、正方形の長さを列挙して、合法かどうかを判断する。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e6+10;
char a[25][25];
bool slove(int x,int y,int n)
{
for(int i=x;i<=x+n;i++)
{
if(a[i][y]!='#')
return false;
if(a[i][y+n]!='#')
return false;
}
for(int i=y;i<=y+n;i++)
{
if(a[x][i]!='#')
return false;
if(a[x+n][i]!='#')
return false;
}
return true;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=0;iscanf("%s",a[i]);
int flag = 0;
for(int i=0;ifor(int j=0;jif(a[i][j]=='#')
{
for(int k=1;k<=n-1-i;k++)
{
if(i+k>=n || j+k>=n)
break;
if(slove(i,j,k))
flag = 1;
}
}
}
}
if(flag)
puts("YES");
else
puts("NO");
}
return 0;
}