写在前面
对于这次组队比赛感慨良多!!一开赛我们还在吃饭,边吃饭边看题,发现1008题是一个水题,直接暴力,然后因为手残错了2次!!!然后就是1009题,不明白这道题为啥比前面一道题过的人多!!这道题一开始的想法就是按位贪心,于是就开始写了,但是发现思维有漏洞,连样例都没有跑过,于是我发现从前到后搜索0的位置即可,如果找到了则把这个0前面的第一个1变成0,然后把从该从0位置到后面的所有数都变成1,队友听了之后敲了敲过了!!然后就是1005题扫雷,队内分析师说这道题只要把第一个点对应的位置确定了下来,后面的也就可以写了,然后代码手一听是可以解决的,很快把代码敲了出来,然后我发现对于上界他没有进行判断,就是有可能该位置是8或者9根本是不可行的,改完交上去过了。对于1001题一看就是个暴力题,手动敲了一发果断超时,看来姿势不对,然后交给队友了,队友对于这类搜索的问题做的太多了,一会就写完了,交上去700+ms顺利1A,对于1003题朋友这道题分析了一会我就感觉这么多次询问,还有修改,如果是深搜搞的话显然不行,于是我就先画了一条链尝试了一下,我发现如果从自己点到叶节点的这条链上的数组合出来的是奇数,那么无论如何修改都会把其变成偶数,同理另一个操作一定把奇、偶数变成奇数,然后我就想每个点一定是跟连与其直接相连的链的权重为1的个数有关,于是敲上去wa了,但是后来发现如果修改边的时候本来权值为1,还修改为1那么自己的程序有漏洞,改过之后AC,然后队友就在最后一题数论题埋头苦干,但是时间不怎么够了,但是他的思想跟赛后的题解的思想是一样的。。
1001
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#define maxn 2030
using namespace std;
int n;
char s[maxn][maxn];
vector<int> v[maxn],rv[maxn];
bool vis[maxn];
bool dfs(int last,int u,char c)
{
int a;
for (int i=0;i<rv[last].size();i++)
{
a=rv[last][i];
if (s[a][u]!=c) return 0;
}
vis[u]=1;
for (int i=0;i<v[u].size();i++) if (!vis[ v[u][i] ])
if (dfs(u,v[u][i],c)==0) return 0;
return 1;
}
int main()
{
int T;
char a='P',b='Q';
scanf("%d",&T) ;
while (T--)
{
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for (int i=0;i<n;i++) scanf("%s",&s[i]);
bool f=0;
//set1
for (int i=0;i<n;i++)
{
v[i].clear(); rv[i].clear();
}
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
if (s[i][j]==a)
{
v[i].push_back(j);
rv[j].push_back(i);
}
}
for (int i=0;i<n;i++) if (!vis[i])
if (dfs(i,i,a)==0)
{
f=1;
break;
}
if (f)
{
printf("N\n");
continue ;
}
//set2
memset(vis,0,sizeof(vis));
for (int i=0;i<n;i++)
{ v[i].clear(); rv[i].clear(); }
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
if (s[i][j]==b)
{
v[i].push_back(j);
rv[j].push_back(i);
}
}
for (int i=0;i<n;i++) if (!vis[i])
if (dfs(i,i,b)==0)
{
f=1;
break;
}
if (f)
{
printf("N\n");
continue ;
}
printf("T\n");
}
return 0;
}
1003
#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 40005;
#define PII pair<int, int>
int degree[maxn];
map <PII, int> M;
int main(){
/*#ifdef LOCAL_BUG
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif // LOCAL_BUG*/
int T, n, m;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
int from, to, val;
M.clear();
memset(degree, 0, sizeof(degree));
for(int i = 1; i < n; i++){
scanf("%d%d%d", &from, &to, &val);
if(val) degree[from]++, degree[to]++;
M.insert(make_pair(make_pair(min(from, to), max(from, to)), val));
}
int op, x, y, z;
while(m--){
scanf("%d", &op);
if(op == 0){
scanf("%d", &x);
if(degree[x]&1) printf("Girls win!\n");
else printf("Boys win!\n");
}
else if(op == 1){
scanf("%d%d%d", &x, &y, &z);
if(z == 1){
if(!M[make_pair(min(x, y), max(x, y))]){
degree[x]++, degree[y]++;
M[make_pair(min(x, y), max(x, y))] = 1;
}
}
else{
if(M[make_pair(min(x, y), max(x, y))]){
degree[x]--, degree[y]--;
M[make_pair(min(x, y), max(x, y))] = 0;
}
}
}
}
}
return 0;
}
1005
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 20005
#define LL long long
#define mod 100000007
using namespace std;
int n,d[maxn];
char s[maxn];
LL cnt;
bool dfs(int dep)
{
int c=s[dep]-'0',boom=0;
if (dep==n-1)
{
boom=d[dep]+d[dep-1];
if (boom==c) return 1;
else return 0;
}
if (dep==0) boom=d[0];
else boom=d[dep-1]+d[dep];
if (c<boom) return 0;
d[dep+1]=c-boom;
if (d[dep+1]>2) return 0;
if (d[dep+1]==1) cnt++;
return dfs(dep+1);
}
LL pow_mod(LL a,LL b)
{
LL ans=1;
while (b)
{
if (b&1) ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
LL ans=0;
scanf("%s",s);
n=strlen(s);
for (int i=0;i<=2;i++)
{
memset(d,0,sizeof(d));
d[0]=i;
if (d[0]==1) cnt=1;
else cnt=0;
if (dfs(0)) ans=(ans+pow_mod(2LL,cnt))%mod;
}
printf("%I64d\n",ans);
}
return 0;
}
1008
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 105;
int a[maxn], b[maxn], sum[maxn][maxn];
int main(){
int T, N, M, x;
scanf("%d", &T);
while(T--){
scanf("%d", &N);
for(int i = 0; i < N; i++)
scanf("%d", &a[i]);
for(int i = 0; i < N; i++){
sum[i][i] = a[i];
for(int j = i+1; j < N; j++)
sum[i][j] = sum[i][j-1]^a[j];
}
scanf("%d", &M);
for(int k = 0; k < M; k++){
scanf("%d", &x);
int ans1 = 0x3f3f3f3f, ans2 = 0;
for(int i = 0; i < N; i++){
for(int j = i; j < N; j++){
if(abs(sum[i][j] - x) < ans1){
ans1 = abs(sum[i][j] - x);
ans2 = (j-i+1);
}
else if(abs(sum[i][j] - x) == ans1) ans2 = max(ans2, (j-i+1));
}
}
printf("%d\n", ans2);
}
printf("\n");
}
return 0;
}
1009
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 100;
int bit[maxn];
int main(){
int T;
scanf("%d", &T);
LL l, r;
while(T--){
scanf("%I64d%I64d", &l, &r);
if(l == r){
printf("%I64d\n", r);
continue;
}
int len = 0;
LL cnt = r;
while(r){
bit[len++] = r%2;
r /= 2;
}
LL sum = 0, temp, ans = 0;
for(int i = len-1; i >= 0; i--){
if(bit[i] == 0){
ans = sum - (1LL<<temp)+(1LL<<(i+1))-1;
if(ans >= l) break;
}
else{
sum += 1LL<<i;
temp = i;
}
}
if(ans >= l) printf("%I64d\n", cnt|ans);
else printf("%I64d\n", cnt);
}
return 0;
}