https://codeforces.com/contest/1138
B:
#include
using namespace std;
const int maxn=1e3+5;
string a,b;
void check(int x,int y,int z,int k)
{
for(int i=0;a[i];i++)
{
if(a[i]=='1'&&b[i]=='0'&&x) //这里奇耻大辱,居然写反了 当时
{
cout<>n)
{
cin>>a>>b;
int x=0,y=0,z=0,k=0;
for(int i=0;a[i];i++)
{
if(a[i]=='1'&&b[i]=='0') x++;
if(a[i]=='0'&&b[i]=='1') y++;
if(a[i]=='1'&&b[i]=='1') z++;
if(a[i]=='0'&&b[i]=='0') k++;
}
int x1,x2,x3,x4 ,y1,y2,y3,y4;
for(int i=0;i<=x;i++)
{
x1=i;
y1=x-i;
for(int j=0;j<=y;j++)
{
x2=j;
y2=y-j;
x3=y2-x1+z;
y3=x1-y2+z;
if(x3%2!=0||y3%2!=0||x3<0||y3<0) continue;
x3/=2;
y3/=2;
x4=n/2-x1-x2-x3;
y4=n/2-y1-y2-y3;
if(x4+y4==k&&x4>=0&&y4>=0)
{
//// cout<<"asd "<
https://codeforces.com/contest/1138/problem/C
题意:
注意一点,是去寻找这一行,和这一列,行和列是单独的。
比如例子中,是因为横行确定为3了之后,所以上面的20才是4,4和 3所在和横行没有关系。
读题也是实力的一部分
题解;
对每一行每一列进行离散化。
然后,取行列的最大值,和行列数所在行列大小的差值和其对应的行列加起来的值的最大值进行比较。
#include
using namespace std;
const int maxn = 1e3 + 5;
struct node
{
node ( int xx, int yy, int zz )
{
x = xx;
y = yy;
v = zz;
}
int x;
int y;
int v;
int m;
};
vector d[maxn];
bool cmp1 ( node a, node b )
{
return a.x < b.x;
}
bool cmp2 ( node a, node b )
{
return a.v < b.v;
}
int hang[maxn], lie[maxn];
int main()
{
int n, m;
while ( cin >> n >> m )
{
int x;
for ( int i = 1; i <= n; i++ )
{
for ( int j = 0; j < m; j++ )
{
// cin>>x;
scanf ( "%d", &x );
d[i].push_back ( node ( x, 0, j ) );
}
sort ( d[i].begin(), d[i].end(), cmp1 );
map tag;
int les = 0;
for ( int j = 0; j < m; j++ )
{
if ( !tag[d[i][j].x] )
{
tag[d[i][j].x] = 1;
les++;
}
d[i][j].y = les;
}
hang[i] = les;
sort ( d[i].begin(), d[i].end(), cmp2 );
}
// cout<<" asd "< temp;
for ( int j = 1; j <= n; j++ )
{
temp.push_back ( node ( d[j][i].x, 0, j ) );
}
map tag;
int les = 0;
sort ( temp.begin(), temp.end(), cmp1 );
for ( int j = 0; j < n; j++ )
{
if ( !tag[temp[j].x] )
{
tag[temp[j].x] = 1;
les++;
}
temp[j].m = les;
}
lie[i] = les;
sort ( temp.begin(), temp.end(), cmp2 );
for ( int j = 0; j < n; j++ )
d[j + 1][i].m = temp[j].m;
}
for ( int i = 1; i <= n; i++ )
{
for ( int j = 0; j < m; j++ )
{
int a = max ( hang[i], lie[j] );
int b = max ( d[i][j].y - d[i][j].m + lie[j], d[i][j].m - d[i][j].y + hang[i] );
cout << max ( a, b ) << ' ';
}
cout << endl;
}
}
}
题意:
构造一个kmp能查出来尽可能子串的串串。
题解:
找一个最大后缀,然后无限构造后缀;直到01不够用
最大的后缀,只需要看看kmp算法中next数组的最后一位是几,就可以了。
然后 对于next数组的位置,一直无限构造后缀,直到01不够用。
赛中突然就失忆了!!!
kmp突然就不会了 ,手突然就残了。
代码真漂亮啊 - -。。。。。。
#include
using namespace std;
const int maxn = 5e5 + 5;
int nex[maxn];
void getnext ( string &b )
{
memset ( nex, 0, sizeof ( nex ) );
for ( int i = 1, j = 0; b[i]; i++ )
{
while ( b[i] != b[j] && j > 0 )
j = nex[j - 1];
if ( b[i] == b[j] )
nex[i] = j + 1, j++;
}
}
int main()
{
string a, b;
while ( cin >> a >> b )
{
getnext ( b );
int x = 0, y = 0;
for ( int i = 0; a[i]; i++ )
a[i] == '0' ? x++ : y++;
string temp;
char c;
int len = b.size();
int num = nex[len - 1], xe = 0, ye = 0, z = 1;
for ( int i = 0;; ++i ,i = i == len ? num : i)
{
if ( i < num && z )
c = b[i];
else
c = b[i], z = 0;
c == '0' ? ++xe : ++ye;
if ( xe > x || ye > y )
break;
temp += c;
}
while ( xe < x )
temp += '0', xe++;
while ( ye < y )
temp += '1', ye++;
cout << temp << endl;
}
}
https://codeforces.com/contest/1138/problem/F
使用龟兔赛跑算法列出s和2*s。
所以 最后的证明是,(m-x) 是圈长的倍数,那么,当点再走(m-x) 步 ,最后则一定相遇。
#include
using namespace std;
int get()
{
int t;
cin>>t;
string s;
for( int i=0 ;i< t;i++)
{
cin>>s;
}
return t;
}
int main()
{
while(1)
{
cout<<"next 0 1"<