#include
using namespace std;
int n,a1,b1,a[10000],b[10000],k1=1,k2=1,sum1,sum2;
int main(){
//freopen("rps.in","r",stdin);
//freopen("rps.out","w",stdout);
cin>>n>>a1>>b1;
for(int i=1;i<=a1;i++){
cin>>a[i];
}
for(int i=1;i<=b1;i++){
cin>>b[i];
}
for(int i=1;i<=n;i++){
if(k1==a1+1){
k1=1;
}
if(k2==b1+1){
k2=1;
}
if(b[k2]==a[k1]){
k1++;
k2++;
continue;
}
if(a[k1]==0){
if(b[k2]!=2&&b[k2]!=3){
sum2++;
}
else sum1++;
}
else if(a[k1]==1){
if(b[k2]!=0&&b[k2]!=3){
sum2++;
}
else sum1++;
}
else if(a[k1]==2){
if(b[k2]!=1&&b[k2]!=4){
sum2++;
}
else sum1++;
}
else if(a[k1]==3){
if(b[k2]!=2&&b[k2]!=4){
sum2++;
}
else sum1++;
}
else if(a[k1]==4){
if(b[k2]!=0&&b[k2]!=1){
sum2++;
}
else sum1++;
}
k1++;k2++;
}
cout<
T2
这道题我拿到是就想到了暴力,先是用vector给每个点加边,然后直接对每个点判断
#include
#define mo 10007
using namespace std;
vectorv[200000];
long long n,a,b,maxx,sum,val,ans;
long long num[200000],x[200000];
void dfs(int n){
sum=0;
for(int i=0;i>n;
for(int i=1;i<=n-1;i++){
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
num[a]++;
num[b]++;
}
for(int i=1;i<=n;i++){
cin>>x[i];
}
for(int i=1;i<=n;i++){
if(num[i]>=2) dfs(i);
}
cout<
但是这样依然不能过,我们可以进一步优化,因为每个点都会计算与之相连的点的乘积,这是就用上了乘法的神奇预算,然后最大值求的时候我们可以先排个序,然后只判断前两个的值即可
#include
#define mo 10007
using namespace std;
vectorv[200000];
long long n,x,y,maxx,sum,val,ans;
long long num[200000],a[200000];
bool cmp(int x,int y){
return a[x]>a[y];
}
int main(){
// freopen("link.in","r",stdin);
//freopen("link.out","w",stdout);
cin>>n;
for(int i=1;i<=n-1;i++){
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;++i){
if(v[i].size()<2) continue;
sort(v[i].begin(),v[i].end(),cmp);
maxx=max(maxx,a[v[i][0]]*a[v[i][1]]);
int s=0;
for(int j=0;j
#include
using namespace std;
int d,n,m,x,y,z,sum,ans1,ans2,lx,ly,rx,ry;
int a[10001][10001];
int main(){
//freopen("wireless.in","r",stdin);
// freopen("wireless.out","w",stdout);
cin>>d;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x>>y>>z;
a[x][y]=z;
}
for(int i=0;i<=128;i++){
lx=max(0,i-d),rx=min(d+i,128);
for(int j=0;j<=128;j++){
ly=max(0,j-d),ry=min(d+j,128);
sum=0;
for(int x=lx;x<=rx;x++){
for(int y=ly;y<=ry;y++){
sum+=a[x][y];
}
}
if(sum>ans2) ans2=sum,ans1=1;
else if(sum==ans2) ans1++;
}
}
cout<
T2
这道题经过dalao讲了一下还是有点思路,多试了几次还是做出来了(自学spfa)。其实主要就是删除不与终点连通的点,以及与他们连一条边的点。删除这个操作我们常用打标记的方法,在枚举图的时候遇到没打标记的点就跳过即可。最后直接跑最短路。
#include
using namespace std;
struct ed{
int u;
int nex;
}e[300000];
int n,m,x,y,d[300000],fir[20000],st,s,t;
bool v[20000],ok[20000],vis[20000];
void add(int u,int v)
{
e[++st].u=u; e[st].nex=fir[v]; fir[v]=st;
}
void spfa(int b) //最短路
{
memset(v,0,sizeof(v));
memset(d,0x3f3f,sizeof(d));
queue q; q.push(b); v[b]=1; d[b]=0;
while (!q.empty())
{
int k=q.front(); q.pop(); v[b]=0;
for (int i=fir[k];i;i=e[i].nex)
{
int u=e[i].u,w=1;
if (d[u]>d[k]+w&&ok[e[i].u]) {
d[u]=d[k]+w;
if (!v[u]) v[u]=1,q.push(u);
}
}
}
}
void bfs(int t) //第一次的搜边
{
memset(v,0,sizeof(v));
queue q; q.push(t); ok[t]=v[t]=1;
while (!q.empty())
{
int k=q.front(); q.pop();
for (int i=fir[k];i;i=e[i].nex)
if (!v[e[i].u]){
int u=e[i].u; if (!v[u]) v[u]=1,ok[u]=1,q.push(u);
}
}
}
int main()
{
cin>>n>>m;
for (int i=1;i<=m;i++) cin>>x>>y,add(x,y);
cin>>s>>t;
bfs(t);
for (int i=1;i<=n;i++) vis[i]=ok[i];
for (int i=1;i<=n;i++)
if (!vis[i]) for (int j=fir[i];j;j=e[j].nex){
if (ok[e[j].u]) ok[e[j].u]=0;
}
spfa(t);
if (d[s]>=(0x3f3f)) cout<<"-1"<
在这里插入代码片
两道T3还没啃透暂时先不贴代码后面再补上。