暴力
范围<=50,直接暴力,用一个函数把范围内的数都反转,sort之解决
#include <bits/stdc++.h>
using namespace std;
int kase;
int l,r;
pair<int,int> arr[60];
int n;
int f(int x)
{
int re=0;
while(x)
{
re*=10;
re+=x%10;
x/=10;
}
return re;
}
int main()
{
//freopen("in.txt","r",stdin);
cin>>kase;
while(kase--)
{
cin>>l>>r;
n=r-l+1;
for(int i=0;i<n;i++)
{
arr[i].second=l+i;
arr[i].first=f(l+i);
}
sort(arr,arr+n);
for(int i=0;i<n;i++)
{
printf("%d",arr[i].second);
if(i==n-1)
putchar(10);
else
putchar(' ');
}
}
return 0;
}
B 最强DE 战斗力
大数+数学
因为战斗力为各部队乘积,所以大部队肯定要拆成小部队了(才看感觉是递归)。输出点小样例可以发现2,3的出镜率非常高。之后就集中注意力考虑拆成2,3了。n=2x+3y,max(z)=2^x*3^y=3^((log3(2)-2/3)x+n/3)。战斗力z和2的部队数负相关,所以尽量多拆3出来了,然后大数水过(bin神模板好,自己胡乱写的大数wa到哭,最后受不了了去网上复制的大数模板,太长所以这里不粘了)
很暴力的bfs
扫一下方程式,然后把里面的反应物和生成物分别提出来,每一个反应物都用数组储存参与了那些方程式。把初始拥有物品压入队列,然后暴力队列中物品参与的反应是否能够发生(反应物都可获得),反应成功的把还未拥有的生成物压入队列。
#include <bits/stdc++.h>
using namespace std;
const int maxn=2000;
int n,m;
string s;
map<string,int> num;
vector<int> in[maxn];
vector<int> out[maxn];
string str[maxn];
int cnt;
bool b[maxn];
queue<int> q;
vector<int> wh[maxn];
string ans[maxn];
int an;
void parse(int x)
{
string t;
int i=0;
for(;;i++)
{
if(s[i]=='+')
{
if(!num.count(t))
{
str[cnt]=t;
num[t]=cnt++;
}
in[x].push_back(num[t]);
wh[num[t]].push_back(x);
t.clear();
}
else if(s[i]=='=')
{
if(!num.count(t))
{
str[cnt]=t;
num[t]=cnt++;
}
in[x].push_back(num[t]);
wh[num[t]].push_back(x);
i++;
t.clear();
break;
}
else
t+=s[i];
}
for(;i<s.size();i++)
{
if(s[i]=='+')
{
if(!num.count(t))
{
str[cnt]=t;
num[t]=cnt++;
}
out[x].push_back(num[t]);
t.clear();
}
else
t+=s[i];
}
if(!num.count(t))
{
str[cnt]=t;
num[t]=cnt++;
}
out[x].push_back(num[t]);
t.clear();
}
void f(int x)
{
for(int i=0;i<in[x].size();i++)
if(b[ in[x][i]]==0)
return ;
for(int i=0;i<out[x].size();i++)
{
int &e =out[x][i];
if(b[e]==0)
{
b[e]=1;
q.push(e);
ans[an++]=str[e];
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
cin>>n;
for(int i=0;i<n;i++)
{
cin>>s;
parse(i);
}
cin>>m;
for(int i=0;i<m;i++)
{
cin>>s;
int x=num[s];
b[x]=1;
q.push(x);
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;i<wh[x].size();i++)
f(wh[x][i]);
}
//for(int i=0;i<cnt;i++)
//cout<<'#'<<num[str[i]]<<str[i]<<endl;
sort(ans,ans+an);
cout<<an<<endl;
for(int i=0;i<an;i++)
cout<<ans[i]<<endl;
return 0;
}
D 遥控器
24K暴力
特判:如果y为个位数且y键完好1次直接按到
暴力:总共才100个台各种乱搞啊,如果--键好的,那么枚举所有能调到的台(3次按到),翻页键好的话计算从所有可能调到的台翻到y的次数
PS:原来的代码有漏洞被一位巨巨hack了orz,没有考虑到x=y的情况,此时应该输出0
#include <bits/stdc++.h>using namespace std;
const int inf = 200;
int kase;
bool arr[13];
int x,y;
int ans;
bool b[100];
int f(int l,int r)
{
if(r>l)
return r-l;
return 100-l+r;
}
int main()
{
//freopen("in.txt","r",stdin);
cin>>kase;
while(kase--)
{
memset(b,0,sizeof(b));
for(int i=1;i<=3;i++)
cin>>arr[i];
cin>>arr[11];
for(int i=4;i<=6;i++)
cin>>arr[i];
cin>>arr[12];
for(int i=7;i<=9;i++)
cin>>arr[i];
cin>>arr[10]>>arr[0];
cin>>x>>y;
if(x==y)
{
cout<<0<<endl;
continue;
}
ans=inf;if(y<10 && arr[y])
{
ans=1;
}
if(arr[10] && arr[y%10] && arr[y/10])
ans=min(ans,3);
for(int i=0;i<=9;i++)
b[i]=arr[i];
if(arr[10])
{
for(int i=0;i<=9;i++)
if(b[i])
for(int j=0;j<=9;j++)
if(b[j])
b[i*10+j]=1;
}
if(arr[11])
{
ans=min(ans,f(x,y));
for(int i=0;i<=9;i++)
if(b[i])
ans=min(ans,f(i,y)+1);
for(int i=10;i<100;i++)
if(b[i])
ans=min(ans,f(i,y)+3);
}
if(arr[12])
{
ans=min(ans,f(y,x));
for(int i=0;i<=9;i++)
if(b[i])
ans=min(ans,f(y,i)+1);
for(int i=10;i<100;i++)
if(b[i])
ans=min(ans,f(y,i)+3);
}
if(ans==inf)
ans=-1;
cout<<ans<<endl;
}
return 0;
}
E 奇妙的图案
此题比赛时候没做出来,后来看的bin神的题解:http://paste.ubuntu.com/10572491/
预处理一下哪两个点可以连接,之后就是dp水过
果然几何太渣啊。。。看完思路之后还是WA了N次才过
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200;
const double eps = 1e-9;
const double INF = 1e10;
int x[maxn];
int y[maxn];
int rx[maxn];
int ry[maxn];
int n,m,r;
bool b[maxn][maxn];
int dp[maxn][maxn];
double dis(int x1,int y1,int x2,int y2)
{
return sqrt(double(y1-y2)*(y1-y2)+double(x1-x2)*(x1-x2));
}
bool ok(int u,int v)
{
double d;
long long x1,x2,y1,y2;
x1=x[u];
x2=x[v];
y1=y[u];
y2=y[v];
for(int ir=0;ir<m;ir++)
{
if((x1-rx[ir])*(x1-x2)+(y1-ry[ir])*(y1-y2)<=0 || (x2-rx[ir])*(x2-x1)+(y2-ry[ir])*(y2-y1)<=0)
{
d=min(dis(x1,y1,rx[ir],ry[ir]),dis(x2,y2,rx[ir],ry[ir]));
}
else
{
if(x1==x2)
{
d=abs(x1-rx[ir]);
}
else
{
d=abs( (x2-x1)*(ry[ir]-y1) - (y2-y1)*(rx[ir]-x1) ) / sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
}
}
if(d < r+eps)
return 0;
}
return 1;
}
int f(int u,int v)
{
if(dp[u][v]!=-1)
return dp[u][v];
dp[u][v]=0;
for(int i=u+1;i<v;i++)
dp[u][v]=max(dp[u][v],f(u,i)+f(i,v)+b[u][i]+b[i][v]);
return dp[u][v];
}
int main()
{
//freopen("in.txt","r",stdin);
cin>>n>>m>>r;
for(int i=0;i<n;i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=0;i<m;i++)
scanf("%d%d",&rx[i],&ry[i]);
for(int i=0;i<n;i++)
for(int j=i+2;j<n;j++)
{
b[i][j]=b[j][i]=ok(i,j);
}
b[0][n-1]=0;
memset(dp,-1,sizeof(dp));
cout<<f(0,n-1);
return 0;
}
F Metric Matrice
太暴力了,已经无话可说,秀个渣风格代码
#include <bits/stdc++.h>
using namespace std;
int kase ;
int n;
const int maxn=40;
int arr[maxn][maxn];
bool b[5];
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&kase);
while(kase--)
{
scanf("%d",&n);
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&arr[i][j]);
for(int i=0;i<n;i++)
if(arr[i][i])
{
b[1]=1;
break;
}
if(b[1])
{
puts("1");
continue;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i==j)
continue;
if(arr[i][j]<=0)
{
b[2]=1;
break;
}
if(arr[i][j]!=arr[j][i])
{
b[3]=1;
break;
}
}
if(b[2]||b[3])
break;
}
if(b[2])
{
puts("2");
continue;
}
if(b[3])
{
puts("3");
continue;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i==j)
continue;
for(int k=0;k<n;k++)
{
if(k==i || k==j)
continue;
if(arr[i][j]+arr[j][k]<arr[i][k])
{
b[4]=1;
break;
}
}
if(b[4])break;
}
if(b[4])
{
puts("4");
continue;
} puts("0");
}
return 0;
}
G Divideing Jewels
又是很暴力的bfs
一看到题就各种琢磨暴力,从价值1的开始一层一层地枚举可能情况储存到数组里,看是否有解(为总价值的一半),然后没有悬念的T了(太暴力了捂脸)
之后想想价值不可能超过1000*10,加了个数组标记所有出现过的情况,水过
PS:总感觉这个方法是要T的,难道是数据太水,巨巨们都说是裸背包,准备要去看背包九讲补补课了orz
#include <bits/stdc++.h>using namespace std;
int arr[11];
int sum;
bool ans;
int kase;
bool b;
bool sss[200000];
vector<int> vi;
int main()
{
//freopen("in.txt","r",stdin);
for(;;)
{
bool ex=0;
for(int i=1;i<=10;i++)
{
scanf("%d",&arr[i]);
if(arr[i])
ex=1;
}
if(ex==0)
break;
if(b)
putchar(10);
b=1;
kase++;
printf("#%d:",kase);
sum=0;
for(int i=1;i<=10;i++)
sum+=i*arr[i];
if(sum%2==1)
{
puts("Can't be divided.");
continue;
}
sum/=2;
ans=0;
vi.clear();
vi.push_back(0);
memset(sss,0,sizeof(sss));
sss[0]=1;
for(int i=1;i<=10;i++)
{
int l=vi.size();
if(ans)
break;
for(int j=0;j<l;j++)
{
if(ans)
break;
for(int k=0;k<=arr[i];k++)
{
int t=vi[j]+k*i;
if(sss[t])
continue;
if(t==sum)
{
ans=1;
break;
}
vi.push_back(t);
sss[t]=1;
}
}
}
puts(ans?"Can be divided.":"Can't be divided.");
}
return 0;
}
H Interesting Punch-Bowl
比赛时候也没做出来。。后来看的胖巨的题解http://blog.csdn.net/kevin66654/article/details/44158575
优先队列,从高度最低的开始搜索
有点坑的就是多组数据没注意看题发现不了。。。又是WA得惊天动地
#include <bits/stdc++.h>
using namespace std;
int c,r;
const int maxn=350;
int arr[maxn][maxn];
bool b[maxn][maxn];
long long ans;
int x[4]={0,0,1,-1};
int y[4]={1,-1,0,0};
struct cmp
{
bool operator()(pair<int,int> a,pair<int,int> b)
{
return arr[a.first][a.second]>arr[b.first][b.second];
}
};
priority_queue<pair<int,int>,vector<pair<int,int> >,cmp > q;
int main()
{
//freopen("in.txt","r",stdin);
while(cin>>c>>r)
{
ans=0;
memset(b,0,sizeof(b));
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
scanf("%d",&arr[i][j]);
for(int i=0;i<=r+1;i++)
b[i][0]=b[i][c+1]=1;
for(int j=0;j<=c+1;j++)
b[0][j]=b[r+1][j]=1;
for(int i=1;i<=r;i++)
{
q.push(make_pair(i,1));
q.push(make_pair(i,c));
b[i][1]=b[i][c]=1;
}
for(int j=2;j<c;j++)
{
q.push(make_pair(1,j));
q.push(make_pair(r,j));
b[1][j]=b[r][j]=1;
}
while(!q.empty())
{
pair<int,int> pi=q.top();
//cout<<pi.first<<' '<<pi.second<<endl;
q.pop();
for(int i=0;i<4;i++)
{
int m=pi.first+x[i];
int n=pi.second+y[i];
if(b[m][n])
continue;
if(arr[m][n]<arr[pi.first][pi.second])
{
ans+=arr[pi.first][pi.second]-arr[m][n];
arr[m][n]=arr[pi.first][pi.second];
//cout<<m<<' '<<n<<' '<<ans<<endl;
}
b[m][n]=1;
q.push(make_pair(m,n));
}
}
cout<<ans<<endl;
}
return 0;
}
总结:果然还是只会暴力暴力的。。。orz而且总是手残WA,继续努力