题目A:
给一个火柴等式,可以从左边移动一根到右边,也可以从右边移到左边,但是不能移动“+”,”=“的火柴,
而且加法里面的数都要大于0(很重要的条件),基本上注意到这点的都过了,没注意的都被HACK了。
#include<iostream>
#include<math.h>
#include<algorithm>
#include<
string>
#include<
set>
#include<map>
using namespace std;
int n;
int main()
{
string s;
cin>>s;
int a,b;
a=b=
0;
int i=
0;
for (;i<s.size();i++)
{
if (s[i]==
‘|‘) a++;
if (s[i]==
‘=‘)
break;
}
for (;i<s.size();i++)
if (s[i]==
‘|‘) b++;
if (abs(a-b)!=
2&&a!=b) cout<<
"Impossible";
else {
if (a==b) cout<<s;
else if (a<b)
{
cout<<
‘|‘;
for (
int i=
0;i<s.size()-
1;i++)
cout<<s[i];
}
else {
if (s[
1]!=
‘+‘)
{
for (
int i=
1;i<s.size();i++)
cout<<s[i];
cout<<
‘|‘;
}
else {
cout<<s[
0]<<s[
1];
s+=
‘|‘;
for (
int i=
3;i<s.size();i++)
cout<<s[i];
}
}
}
cout<<endl;
return 0;
}
B:
吐槽的小学奥数题: A1A2A3A3...AN*X=ANA1A2A3....AN-1;
还有个限制就是让满足条件的A1A2A3A4..AN字典序最小
方法是:枚举AN,然后保存可行方案,判段一下。。。
丑丑的代码:
#include<iostream>
#include<math.h>
#include<algorithm>
#include<
string>
#include<
set>
#include<map>
using namespace std;
int a[
2000000];
int b[
2000000];
int p,x;
void pan()
{
int flag=
0;
for (
int i=p;i>=
1;i--)
if (b[i]>a[i])
{
flag=
1;
break;
}
if (flag)
for (
int i=p;i>=
1;i--)
b[i]=a[i];
}
int main()
{
cin>>p>>x;
/*if (x==1)
{
cout<<1;
for (int i=1;i<p-1;i++)
cout<<0;
if (p>1) cout<<1<<endl;
return 0;
}*/ for (
int i=
1;i<=p;i++)
b[i]=
9;
int flag=
0;
for (
int i=
9;i>=
1;i--)
{
int next=i;
int tem=
0;
for (
int j=
1;j<=p;j++)
{
a[j]=next;
tem=next*x+tem/
10;
next=tem%
10;
}
if (tem==i) {
if (a[p]!=
0&&a[
1]!=
0) {flag=
1;pan();}
}
}
if (flag)
{
for (
int j=p;j>=
1;j--)
cout<<b[j];
}
else cout<<
"Impossible";
cout<<endl;
return 0;
}
还是比赛快10分钟结束的时候出的,弱。。。。
代码风格不是很好,建议不要看代码了。。。。。。^^
C:
这几天一直在想C,D题,其实题目也很好理解
先初始所有的为“00”
先从左往右放"11",
然后放"01","10";后面的就不应管了,程序也相应比较简单,不过自己的编码能力。。。。不吐槽了
#include<iostream>
#include<
string>
using namespace std;
string s[
1001][
1001];
int n,m,sum;
int k;
int main()
{
cin>>n>>m;
for (
int i=
1;i<=n;i++)
for (
int j=
1;j<=m;j++)
{
cin>>s[i][j];
if (s[i][j]==
"11") k++;
if (s[i][j][
0]==
‘1‘) sum++;
if (s[i][j][
1]==
‘1‘) sum++;
}
//cout<<endl;
for (
int i=
1;i<=n;i++)
for (
int j=
1;j<=m;j++)
s[i][j]=
"00";
for (
int t=
1;t<=n;t++)
for (
int i=
1;i<=m;i++)
if (s[t][i]==
"00")
{
if (k) {s[t][i]=
"11";k--;sum-=
2;}
else {
int y=t;
// while (s[y][i]!="00") y++;
if (sum&&(y<=n)) {s[y][i]=
"10";sum--;y++;}
if (sum&&(y<=n)) {s[y][i]=
"01";sum--;}
}
}
for (
int i=
1;i<=n;i++)
{
for (
int j=
1;j<m;j++)
cout<<s[i][j]<<
" ";
cout<<s[i][m]<<endl;
}
return 0;
}
D题:二分STEP;然后O(N*N) 判断可行性,这里我参考了某位大牛的方法,后来自己也小证明了一下
[
A[I]-STEP,A[I]+STEP],这是第I个可能达到的值,然后枚举公差,问题的关键是怎样判断是否可行
假如枚举到公差的D,第N个的数值能达到的是[A[N]-STEP,A[N]+STEP],第N-1个可能的是[A[N-1]-step,A[N-1]+STEP]与[A[N]-STEP-D,A[N]+STEP-D]的交集
于是[MAX(A[N-1]-STEP,A[N]-STEP-D),MIN(A[N-1]+STEP,A[N]+STEP-D)];
CODE:#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
int a[
2000],n;
int ans,up,down,yy;
int pan(
int Max)
{
for (
int d=
0;d<=
20000;d++)
{
up=a[n]+Max;
down=a[n]-Max;
for (
int i=n-
1;i>=
1;i--)
{
up=min(up-d,a[i]+Max);
down=max(down-d,a[i]-Max);
}
if (down<=up) {
ans=d;yy=down;
return 1;}
}
return 0;
}
int main()
{
cin>>n;
for (
int i=
1;i<=n;i++)
cin>>a[i];
sort(a+
1,a+n+
1);
int l=
0,r=
999999;
while (l<r)
{
int mid=(l+r)/
2;
if (pan(mid)) r=mid;
else l=mid+
1;
}
cout<<l<<endl<<yy<<
" "<<ans<<endl;
return 0;
}
这里是那位大大的BLOG:http://blog.csdn.net/accelerator_/article/details/19670387
比我的详细的好多了
Codeforces Round #231 (Div2) 迟到的解题报告
原文:http://www.cnblogs.com/forgot93/p/3567203.html